#define PERL_NO_GET_CONTEXT #define MATH_INT64_NATIVE_IF_AVAILABLE #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "perl_math_int64.h" #include "ppport.h" #include "highwayhash.c" typedef HighwayHashCat* Digest__HighwayHash; void process_key(pTHX_ AV *key_av, uint64_t *key) { int i; SV *elt; if(av_len(key_av) + 1 != 4) croak("Key for highway_hash must be a 4-element array"); for(i = 0 ; i < 4 ; i++) { elt = *av_fetch(key_av, i, 0); if(SvU64OK(elt)) key[i] = SvU64(elt); else key[i] = SvUV(elt); } } uint64_t highway_hash64(AV *key_av, unsigned char *bytes, size_t size) { dTHX; uint64_t key[4]; process_key(aTHX_ key_av, key); return HighwayHash64(bytes, size, key); } AV* highway_hash128(AV *key_av, unsigned char *bytes, size_t size) { dTHX; AV* result; uint64_t key[4]; uint64_t hash[2]; process_key(aTHX_ key_av, key); HighwayHash128(bytes, size, key, hash); result = newAV(); av_push(result, sv_2mortal(newSVu64(hash[0]))); av_push(result, sv_2mortal(newSVu64(hash[1]))); return result; } AV* highway_hash256(AV *key_av, unsigned char *bytes, size_t size) { dTHX; AV* result; uint64_t key[4]; uint64_t hash[4]; process_key(aTHX_ key_av, key); HighwayHash256(bytes, size, key, hash); result = newAV(); av_push(result, sv_2mortal(newSVu64(hash[0]))); av_push(result, sv_2mortal(newSVu64(hash[1]))); av_push(result, sv_2mortal(newSVu64(hash[2]))); av_push(result, sv_2mortal(newSVu64(hash[3]))); return result; } Digest__HighwayHash new(AV *key_av) { dTHX; uint64_t key[4]; Digest__HighwayHash state; Newx(state, 1, HighwayHashCat); process_key(aTHX_ key_av, key); HighwayHashCatStart(key, state); return state; } void append(Digest__HighwayHash state, unsigned char *bytes, size_t size) { HighwayHashCatAppend(bytes, size, state); } uint64_t finish64(Digest__HighwayHash state) { return HighwayHashCatFinish64(state); } AV* finish128(Digest__HighwayHash state) { dTHX; AV* result; uint64_t hash[2]; HighwayHashCatFinish128(state, hash); result = newAV(); av_push(result, sv_2mortal(newSVu64(hash[0]))); av_push(result, sv_2mortal(newSVu64(hash[1]))); return result; } AV* finish256(Digest__HighwayHash state) { dTHX; AV* result; uint64_t hash[4]; HighwayHashCatFinish256(state, hash); result = newAV(); av_push(result, sv_2mortal(newSVu64(hash[0]))); av_push(result, sv_2mortal(newSVu64(hash[1]))); av_push(result, sv_2mortal(newSVu64(hash[2]))); av_push(result, sv_2mortal(newSVu64(hash[3]))); return result; } MODULE = Digest::HighwayHash PACKAGE = Digest::HighwayHash PROTOTYPES: DISABLE BOOT: PERL_MATH_INT64_LOAD_OR_CROAK; uint64_t highway_hash64(AV *key_av, unsigned char *bytes, size_t length(bytes)) AV* highway_hash128(AV *key_av, unsigned char *bytes, size_t length(bytes)) AV* highway_hash256(AV *key_av, unsigned char *bytes, size_t length(bytes)) Digest::HighwayHash new(SV *class, AV *key_av) C_ARGS: key_av void append(Digest::HighwayHash state, unsigned char *bytes, size_t length(bytes)) uint64_t finish64(Digest::HighwayHash state) AV* finish128(Digest::HighwayHash state) AV* finish256(Digest::HighwayHash state)