summaryrefslogtreecommitdiff
path: root/inc/CryptX_Checksum_Adler32.xs.inc
blob: 6b2292aea8efa81c5ce1645959b72e92c35739bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
MODULE = CryptX         PACKAGE = Crypt::Checksum::Adler32

PROTOTYPES: DISABLE

Crypt::Checksum::Adler32
new(Class)
    CODE:
    {
        Newz(0, RETVAL, 1, adler32_state);
        if (!RETVAL) croak("FATAL: Newz failed");
        adler32_init(RETVAL); /* returns void */
    }
    OUTPUT:
        RETVAL

void
DESTROY(Crypt::Checksum::Adler32 self)
    CODE:
        Safefree(self);

void
reset(Crypt::Checksum::Adler32 self)
    PPCODE:
    {
        adler32_init(self); /* returns void */
        XPUSHs(ST(0)); /* return self */
    }

Crypt::Checksum::Adler32
clone(Crypt::Checksum::Adler32 self)
    CODE:
        Newz(0, RETVAL, 1, adler32_state);
        if (!RETVAL) croak("FATAL: Newz failed");
        Copy(self, RETVAL, 1, adler32_state);
    OUTPUT:
        RETVAL

void
add(Crypt::Checksum::Adler32 self, ...)
    PPCODE:
    {
        STRLEN inlen;
        int i;
        unsigned char *in;
        for(i=1; i<items; i++) {
          in = (unsigned char *)SvPVbyte(ST(i), inlen);
          if (inlen > 0) {
            adler32_update(self, in, (unsigned long)inlen); /* returns void */
          }
        }
        XPUSHs(ST(0)); /* return self */
    }

SV *
digest(Crypt::Checksum::Adler32 self)
    ALIAS:
        hexdigest = 1
        intdigest = 2
    CODE:
    {
        int rv;
        unsigned char hash[4], out[9];
        unsigned long outlen = 9;
        unsigned int ui32;

        adler32_finish(self, hash, 4); /* returns void */
        if (ix == 1) {
          rv = base16_encode(hash, 4, out, &outlen, 0);
          if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv));
          RETVAL = newSVpvn((char *)out, outlen);
        }
        else if (ix == 2) {
          LOAD32H(ui32, hash);
          RETVAL = newSVuv(ui32);
        }
        else {
          RETVAL = newSVpvn((char *) hash, 4);
        }
    }
    OUTPUT:
        RETVAL

SV *
adler32_data(...)
    ALIAS:
        adler32_data_hex = 1
        adler32_data_int = 2
    CODE:
    {
        adler32_state st;
        int rv, j;
        unsigned char hash[4], out[9], *in;
        unsigned long outlen = 9;
        unsigned int ui32;
        STRLEN inlen;

        adler32_init(&st);
        for(j = 0; j < items; j++) {
          in = (unsigned char *)SvPVbyte(ST(j), inlen);
          if (inlen > 0) {
            adler32_update(&st, in, (unsigned long)inlen); /* returns void */
          }
        }
        adler32_finish(&st, hash, 4); /* returns void */
        if (ix == 1) {
          rv = base16_encode(hash, 4, out, &outlen, 0);
          if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv));
          RETVAL = newSVpvn((char *)out, outlen);
        }
        else if (ix == 2) {
          LOAD32H(ui32, hash);
          RETVAL = newSVuv(ui32);
        }
        else {
          RETVAL = newSVpvn((char *) hash, 4);
        }
    }
    OUTPUT:
        RETVAL