1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4 #include "ppport.h"
5 #include "upstream/Whirlpool.c"
6 
7 typedef struct whirlpool {
8     NESSIEstruct state;
9 }* Digest__Whirlpool;
10 
11 MODULE = Digest::Whirlpool		PACKAGE = Digest::Whirlpool
12 PROTOTYPES: DISABLE
13 
14 SV *
15 new(SV * class)
16 CODE:
17     Digest__Whirlpool self;
18     const char * pkg;
19 
20     /* Figure out what class we're supposed to bless into, handle
21        $obj->new (for completeness) and Class->new  */
22     if (SvROK(class)) {
23         /* An object, get is type */
24         pkg = sv_reftype(SvRV(class), TRUE);
25     } else {
26         /* If this function gets called as Pkg->new the value being passed is
27          * a READONLY SV so we'll need a copy
28          */
29         pkg = SvPV(class, PL_na);
30     }
31 
32     /* Allocate memory for Whirlpool's store and create an IV ref
33        containing its memory location */
34     Newz(0, self, 1, struct whirlpool);
35     NESSIEinit(&self->state);
36 
37     RETVAL = newSV(0); /* This gets mortalized automagically */
38     sv_setref_pv(RETVAL, pkg, (void*)self);
39 OUTPUT:
40     RETVAL
41 
42 Digest::Whirlpool
43 clone(self)
44     Digest::Whirlpool self
45     CODE:
46         Newz(0, RETVAL, 1, struct whirlpool);
47         Copy(&self->state, &RETVAL->state, 1, struct whirlpool);
48     OUTPUT:
49         RETVAL
50 
51 int
52 hashsize(...)
53     CODE:
54         PERL_UNUSED_VAR(items);
55         RETVAL = 512;
56     OUTPUT:
57         RETVAL
58 
59 Digest::Whirlpool
60 reset(self)
61     Digest::Whirlpool self
62     CODE:
63         PERL_UNUSED_VAR(RETVAL);
64         NESSIEinit(&self->state);
65     OUTPUT:
66 
67 Digest::Whirlpool
68 add(self, ...)
69     Digest::Whirlpool self
70     CODE:
71     {
72         STRLEN len;
73         unsigned char* data;
74         unsigned int i;
75 
76         PERL_UNUSED_VAR(RETVAL);
77 
78         for (i = 1; i < items; i++) {
79             data = (unsigned char*)(SvPV(ST(i), len));
80             NESSIEadd(data, len << 3, &self->state);
81         }
82     }
83     OUTPUT:
84 
85 SV*
86 digest(self)
87     Digest::Whirlpool self
88     CODE:
89     {
90         unsigned char* data;
91         /* A bit (tr)?icky, makes sure the SvPV is 64 bytes then grabs
92            its char* part and writes directly to it */
93         RETVAL = newSVpvn("", 64);
94         data = (unsigned char*)SvPVX(RETVAL);
95         NESSIEfinalize(&self->state, data);
96         NESSIEinit(&self->state);
97     }
98 
99     OUTPUT:
100         RETVAL
101 
102 void
103 DESTROY(self)
104     Digest::Whirlpool self
105     CODE:
106         Safefree(self);
107 
108