Skip to content

Commit 5149e47

Browse files
committed
FEAT: added functional /PART and /SEEK refinements for WRITE action on CHECKSUM port
Possible usage: data: #{0bad} port: open checksum:// sum1: read write port bin sum2: read write/part open port tail bin -2 ;port was restarted using OPEN sum3: read write/seek/part open port bin 2 -2 all [sum1 = sum2 sum1 = sum3] ;== true
1 parent 9285dfd commit 5149e47

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/core/p-checksum.c

+26-4
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
REBVAL *method;
100100
REBREQ *req;
101101
REBVAL *arg;
102+
REBCNT args = 0;
102103
REBVAL *data;
103104
REBVAL *ctx;
104105
REBYTE *temp;
@@ -128,16 +129,38 @@
128129
Checksum_Open(port, method, ctx_size);
129130
SET_OPEN(req);
130131
}
132+
args = Find_Refines(ds, ALL_WRITE_REFS);
131133
arg = D_ARG(2);
134+
REBYTE *bin = VAL_BIN_DATA(arg);
135+
REBI64 pos = (REBI64)VAL_INDEX(arg);
136+
if (args & AM_WRITE_SEEK) {
137+
pos += Int64(D_ARG(ARG_WRITE_INDEX));
138+
if(pos < 0) pos = 0;
139+
else if (pos > VAL_TAIL(arg)) pos = VAL_TAIL(arg);
140+
}
141+
REBI64 part = (REBI64)VAL_TAIL(arg) - pos;
142+
if (args & AM_WRITE_PART) {
143+
REBI64 cnt = Int64(D_ARG(ARG_WRITE_LENGTH));
144+
if(cnt < 0) {
145+
cnt = -cnt;
146+
pos -= cnt;
147+
if (pos < 0) {
148+
cnt += pos;
149+
pos = 0;
150+
}
151+
part = cnt;
152+
} else if (cnt < part) part = cnt;
153+
}
154+
if(part <= 0) return R_RET;
132155
switch (VAL_WORD_CANON(method)) {
133156
case SYM_MD5:
134-
MD5_Update((MD5_CTX*)VAL_BIN(ctx), VAL_BIN_DATA(arg), VAL_TAIL(arg) - VAL_INDEX(arg));
157+
MD5_Update((MD5_CTX*)VAL_BIN(ctx), VAL_BIN_SKIP(arg, pos), part);
135158
break;
136159
case SYM_SHA1:
137-
SHA1_Update((SHA_CTX*)VAL_BIN(ctx), VAL_BIN_DATA(arg), VAL_TAIL(arg) - VAL_INDEX(arg));
160+
SHA1_Update((SHA_CTX*)VAL_BIN(ctx), VAL_BIN_SKIP(arg, pos), part);
138161
break;
139162
case SYM_SHA256:
140-
SHA256_Update((SHA256_CTX*)VAL_BIN(ctx), VAL_BIN_DATA(arg), VAL_TAIL(arg) - VAL_INDEX(arg));
163+
SHA256_Update((SHA256_CTX*)VAL_BIN(ctx), VAL_BIN_SKIP(arg, pos), part);
141164
break;
142165
}
143166
break;
@@ -176,7 +199,6 @@
176199
return R_RET;
177200

178201
case A_OPEN:
179-
if (IS_OPEN(req)) return R_RET;
180202
if (Checksum_Open(port, method, ctx_size)) {
181203
SET_OPEN(req);
182204
} else {

src/tests/units/checksum-test.r3

+19
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,25 @@ Rebol [
7777
--assert sum1 = port/data
7878
close port
7979

80+
--test-- "checksum-write-refinements"
81+
port: open checksum://
82+
write/part port bin 1
83+
write/part port next bin 1
84+
sum1: checksum/method bin port/spec/method
85+
sum2: checksum/method join bin bin port/spec/method
86+
--assert sum1 = read port
87+
--assert sum1 = read write/part port bin 0
88+
--assert sum1 = read write/part port bin -1
89+
--assert sum2 = read write/part port tail bin -2
90+
port: open checksum://
91+
--assert sum1 = read write/seek/part port #{cafe0bad} 2 2
92+
;opening already opened port restarts computation
93+
--assert sum1 = read write/seek/part open port #{cafe0bad} 2 2
94+
--assert sum1 = read write/seek/part open port tail #{cafe0bad} -2 2
95+
96+
97+
98+
8099
===end-group===
81100

82101
~~~end-file~~~

0 commit comments

Comments
 (0)