#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)