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
120
121
122
123
124
125
126
127
|
#include <imprison.h>
#include <jets/k.h>
#include <log.h>
#include <nock.h>
#include <retrieve.h>
#include <types.h>
#include <xtract.h>
static void _x_octs(u3_noun octs, u3_atom* p_octs, u3_atom* q_octs) {
if (c3n == u3r_mean(octs,
2, p_octs,
3, q_octs, 0)){
u3m_bail(c3__exit);
}
if (c3n == u3a_is_atom(*p_octs) ||
c3n == u3a_is_atom(*q_octs)) {
u3m_bail(c3__exit);
}
}
static c3_o _x_octs_buffer(u3_atom* p_octs, u3_atom *q_octs,
c3_w* p_octs_w, c3_y** buf_y,
c3_w* len_w, c3_w* lead_w)
{
if (c3n == u3r_safe_word(*p_octs, p_octs_w)) {
return c3n;
}
*len_w = u3r_met(3, *q_octs);
if (c3y == u3a_is_cat(*q_octs)) {
*buf_y = (c3_y*)q_octs;
}
else {
u3a_atom* ptr_a = u3a_to_ptr(*q_octs);
*buf_y = (c3_y*)ptr_a->buf_w;
}
*lead_w = 0;
if (*p_octs_w > *len_w) {
*lead_w = *p_octs_w - *len_w;
}
else {
*len_w = *p_octs_w;
}
return c3y;
}
#define BASE 65521
#define NMAX 5552
u3_noun _qe_adler32(u3_noun octs)
{
u3_atom p_octs, q_octs;
_x_octs(octs, &p_octs, &q_octs);
c3_w p_octs_w, len_w, lead_w;
c3_y *buf_y;
if (c3n == _x_octs_buffer(&p_octs, &q_octs,
&p_octs_w, &buf_y,
&len_w, &lead_w)) {
return u3_none;
}
c3_w adler_w, sum2_w;
adler_w = 0x1;
sum2_w = 0x0;
c3_w pos_w = 0;
// Process all non-zero bytes
//
while (pos_w < len_w) {
c3_w rem_w = (len_w - pos_w);
if (rem_w > NMAX) {
rem_w = NMAX;
}
while (rem_w--) {
adler_w += *(buf_y + pos_w++);
sum2_w += adler_w;
}
adler_w %= BASE;
sum2_w %= BASE;
}
// Process leading zeros
//
while (pos_w < p_octs_w) {
c3_w rem_w = (p_octs_w - pos_w);
if (rem_w > NMAX) {
rem_w = NMAX;
}
// leading zeros: adler sum is unchanged
sum2_w += rem_w*adler_w;
pos_w += rem_w;
adler_w %= BASE;
sum2_w %= BASE;
}
return u3i_word(sum2_w << 16 | adler_w);
}
u3_noun
u3we_adler32(u3_noun cor)
{
u3_noun octs;
u3x_mean(cor, u3x_sam, &octs, 0);
return _qe_adler32(octs);
}
|