yencode 1.1.5 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +130 -189
  2. package/binding.gyp +115 -6
  3. package/index.js +2 -0
  4. package/package.json +1 -1
  5. package/src/common.h +37 -7
  6. package/src/crc.cc +121 -47
  7. package/src/crc.h +74 -10
  8. package/src/crc_arm.cc +51 -34
  9. package/src/crc_arm_pmull.cc +215 -0
  10. package/src/crc_common.h +22 -0
  11. package/src/crc_folding.cc +154 -16
  12. package/src/crc_folding_256.cc +7 -14
  13. package/src/crc_riscv.cc +251 -0
  14. package/src/decoder.cc +373 -13
  15. package/src/decoder.h +10 -14
  16. package/src/decoder_avx.cc +5 -6
  17. package/src/decoder_avx2.cc +8 -9
  18. package/src/decoder_avx2_base.h +7 -11
  19. package/src/decoder_common.h +56 -373
  20. package/src/decoder_neon.cc +13 -19
  21. package/src/decoder_neon64.cc +12 -15
  22. package/src/decoder_rvv.cc +280 -0
  23. package/src/decoder_sse2.cc +26 -5
  24. package/src/decoder_sse_base.h +20 -40
  25. package/src/decoder_ssse3.cc +5 -6
  26. package/src/decoder_vbmi2.cc +6 -13
  27. package/src/encoder.cc +42 -26
  28. package/src/encoder.h +5 -7
  29. package/src/encoder_avx.cc +3 -3
  30. package/src/encoder_avx2.cc +3 -3
  31. package/src/encoder_avx_base.h +3 -0
  32. package/src/encoder_common.h +26 -32
  33. package/src/encoder_neon.cc +6 -3
  34. package/src/encoder_rvv.cc +13 -26
  35. package/src/encoder_sse2.cc +3 -2
  36. package/src/encoder_sse_base.h +2 -0
  37. package/src/encoder_ssse3.cc +3 -3
  38. package/src/encoder_vbmi2.cc +6 -7
  39. package/src/platform.cc +24 -23
  40. package/src/yencode.cc +54 -11
  41. package/test/_speedbase.js +4 -2
  42. package/test/speeddec.js +25 -16
  43. package/test/speedenc.js +21 -17
  44. package/test/testcrc.js +17 -1
  45. package/test/testcrcfuncs.c +53 -0
  46. package/test/testdec.js +1 -0
package/src/yencode.cc CHANGED
@@ -11,6 +11,7 @@
11
11
  #include "crc.h"
12
12
 
13
13
  using namespace v8;
14
+ using namespace RapidYenc;
14
15
 
15
16
  static void free_buffer(char* data, void* _size) {
16
17
  #if !NODE_VERSION_AT_LEAST(0, 11, 0)
@@ -129,7 +130,7 @@ FUNC(Encode) {
129
130
  size_t dest_len = YENC_MAX_SIZE(arg_len, line_size);
130
131
 
131
132
  unsigned char *result = (unsigned char*) malloc(dest_len);
132
- size_t len = do_encode(line_size, &col, (const unsigned char*)node::Buffer::Data(args[0]), result, arg_len, true);
133
+ size_t len = encode(line_size, &col, (const unsigned char*)node::Buffer::Data(args[0]), result, arg_len, true);
133
134
  result = (unsigned char*)realloc(result, len);
134
135
  MARK_EXT_MEM(len);
135
136
  RETURN_VAL( NEW_BUFFER((char*)result, len, free_buffer, (void*)len) );
@@ -164,7 +165,7 @@ FUNC(EncodeTo) {
164
165
  if(node::Buffer::Length(args[1]) < dest_len)
165
166
  RETURN_ERROR("Destination buffer does not have enough space (use `maxSize` to compute required space)");
166
167
 
167
- size_t len = do_encode(line_size, &col, (const unsigned char*)node::Buffer::Data(args[0]), (unsigned char*)node::Buffer::Data(args[1]), arg_len, true);
168
+ size_t len = encode(line_size, &col, (const unsigned char*)node::Buffer::Data(args[0]), (unsigned char*)node::Buffer::Data(args[1]), arg_len, true);
168
169
  RETURN_VAL( Integer::New(ISOLATE len) );
169
170
  }
170
171
 
@@ -220,7 +221,7 @@ FUNC(EncodeIncr) {
220
221
  result = (unsigned char*) malloc(dest_len);
221
222
  }
222
223
 
223
- size_t len = do_encode(line_size, &col, (const unsigned char*)node::Buffer::Data(args[0]), result, arg_len, false);
224
+ size_t len = encode(line_size, &col, (const unsigned char*)node::Buffer::Data(args[0]), result, arg_len, false);
224
225
 
225
226
  SET_OBJ(ret, "written", Integer::New(ISOLATE len));
226
227
  if(allocResult) {
@@ -247,7 +248,7 @@ FUNC(Decode) {
247
248
  isRaw = ARG_TO_BOOL(args[1]);
248
249
 
249
250
  unsigned char *result = (unsigned char*) malloc(arg_len);
250
- size_t len = do_decode(isRaw, (const unsigned char*)node::Buffer::Data(args[0]), result, arg_len, NULL);
251
+ size_t len = decode(isRaw, (const unsigned char*)node::Buffer::Data(args[0]), result, arg_len, NULL);
251
252
  result = (unsigned char*)realloc(result, len);
252
253
  MARK_EXT_MEM(len);
253
254
  RETURN_VAL( NEW_BUFFER((char*)result, len, free_buffer, (void*)len) );
@@ -271,7 +272,7 @@ FUNC(DecodeTo) {
271
272
  if (args.Length() > 2)
272
273
  isRaw = ARG_TO_BOOL(args[2]);
273
274
 
274
- size_t len = do_decode(isRaw, (const unsigned char*)node::Buffer::Data(args[0]), (unsigned char*)node::Buffer::Data(args[1]), arg_len, NULL);
275
+ size_t len = decode(isRaw, (const unsigned char*)node::Buffer::Data(args[0]), (unsigned char*)node::Buffer::Data(args[1]), arg_len, NULL);
275
276
  RETURN_VAL( Integer::New(ISOLATE len) );
276
277
  }
277
278
 
@@ -310,7 +311,7 @@ FUNC(DecodeIncr) {
310
311
 
311
312
  if(allocResult) result = (unsigned char*) malloc(arg_len);
312
313
  unsigned char* dp = result;
313
- YencDecoderEnd ended = do_decode_end(&sp, &dp, arg_len, &state);
314
+ YencDecoderEnd ended = RapidYenc::decode_end((const void**)&sp, (void**)&dp, arg_len, &state);
314
315
  size_t len = dp - result;
315
316
  if(allocResult) result = (unsigned char*)realloc(result, len);
316
317
 
@@ -363,7 +364,7 @@ FUNC(CRC32) {
363
364
  RETURN_ERROR("Second argument must be a 4 byte buffer");
364
365
  crc = read_crc32(args[1]);
365
366
  }
366
- crc = do_crc32(
367
+ crc = crc32(
367
368
  (const void*)node::Buffer::Data(args[0]),
368
369
  node::Buffer::Length(args[0]),
369
370
  crc
@@ -383,7 +384,7 @@ FUNC(CRC32Combine) {
383
384
  uint32_t crc1 = read_crc32(args[0]), crc2 = read_crc32(args[1]);
384
385
  size_t len = (size_t)ARG_TO_INT(args[2]);
385
386
 
386
- crc1 = do_crc32_combine(crc1, crc2, len);
387
+ crc1 = crc32_combine(crc1, crc2, len);
387
388
  RETURN_VAL(pack_crc32(ISOLATE crc1));
388
389
  }
389
390
 
@@ -399,15 +400,55 @@ FUNC(CRC32Zeroes) {
399
400
  RETURN_ERROR("Second argument must be a 4 byte buffer");
400
401
  crc1 = read_crc32(args[1]);
401
402
  }
402
- size_t len = (size_t)ARG_TO_INT(args[0]);
403
- crc1 = do_crc32_zeros(crc1, len);
403
+ int len = ARG_TO_INT(args[0]);
404
+ if(len < 0)
405
+ crc1 = crc32_unzero(crc1, -len);
406
+ else
407
+ crc1 = crc32_zeros(crc1, len);
404
408
  RETURN_VAL(pack_crc32(ISOLATE crc1));
405
409
  }
406
410
 
411
+ FUNC(CRC32Multiply) {
412
+ FUNC_START;
413
+
414
+ if (args.Length() < 2)
415
+ RETURN_ERROR("At least 2 arguments required");
416
+
417
+ if (!node::Buffer::HasInstance(args[0]) || node::Buffer::Length(args[0]) != 4
418
+ || !node::Buffer::HasInstance(args[1]) || node::Buffer::Length(args[1]) != 4)
419
+ RETURN_ERROR("You must supply a 4 byte Buffer for the first two arguments");
420
+
421
+ uint32_t crc1 = read_crc32(args[0]);
422
+ uint32_t crc2 = read_crc32(args[1]);
423
+ crc1 = crc32_multiply(crc1, crc2);
424
+ RETURN_VAL(pack_crc32(ISOLATE crc1));
425
+ }
426
+
427
+ FUNC(CRC32Shift) {
428
+ FUNC_START;
429
+
430
+ if (args.Length() < 1)
431
+ RETURN_ERROR("At least 1 argument required");
432
+
433
+ uint32_t crc1 = 0x80000000;
434
+ if (args.Length() >= 2) {
435
+ if (!node::Buffer::HasInstance(args[1]) || node::Buffer::Length(args[1]) != 4)
436
+ RETURN_ERROR("Second argument must be a 4 byte buffer");
437
+ crc1 = read_crc32(args[1]);
438
+ }
439
+ int n = ARG_TO_INT(args[0]);
440
+ if(n < 0)
441
+ crc1 = crc32_shift(crc1, ~crc32_powmod(-n));
442
+ else
443
+ crc1 = crc32_shift(crc1, crc32_powmod(n));
444
+ RETURN_VAL(pack_crc32(ISOLATE crc1));
445
+ }
446
+
447
+
407
448
  static void init_all() {
408
449
  encoder_init();
409
450
  decoder_init();
410
- crc_init();
451
+ crc32_init();
411
452
  }
412
453
 
413
454
  #if NODE_VERSION_AT_LEAST(10, 7, 0)
@@ -436,6 +477,8 @@ void yencode_init(
436
477
  NODE_SET_METHOD(exports, "crc32", CRC32);
437
478
  NODE_SET_METHOD(exports, "crc32_combine", CRC32Combine);
438
479
  NODE_SET_METHOD(exports, "crc32_zeroes", CRC32Zeroes);
480
+ NODE_SET_METHOD(exports, "crc32_multiply", CRC32Multiply);
481
+ NODE_SET_METHOD(exports, "crc32_shift", CRC32Shift);
439
482
 
440
483
  #if NODE_VERSION_AT_LEAST(10, 7, 0)
441
484
  uv_once(&init_once, init_all);
@@ -81,12 +81,14 @@ module.exports = {
81
81
  module.exports._benchAsync(fn, cb, trials, []);
82
82
  }, asyncWait);
83
83
  },
84
- run: function(name, fn, sz2) {
84
+ run: function(name, fn, sz2, fn2) {
85
85
  var time = module.exports.bench(fn);
86
+ var time2 = fn2 ? module.exports.bench(fn2) : null;
86
87
  console.log(
87
88
  (name+' ').substring(0, 25) + ':'
88
89
  + fmtSpeed(sz*rounds, time)
89
- + (sz2 ? (' ' + fmtSpeed(sz2*rounds, time)) : '')
90
+ + ' ' + (sz2 ? fmtSpeed(sz2*rounds, time) : ' ')
91
+ + ' ' + (fn2 ? fmtSpeed(sz*rounds, time2) : ' ')
90
92
  );
91
93
  },
92
94
 
package/test/speeddec.js CHANGED
@@ -30,7 +30,7 @@ _.bufAvg2x.forEach(function(buf, i) {
30
30
 
31
31
  _.parseArgs('Syntax: node test/speeddec [-a|--average-only] [{-s|--sleep}=msecs(0)] [{-m|--methods}=clean,raw,rawincr]');
32
32
 
33
- console.log(' Test Output rate Read rate ');
33
+ console.log(' Test Output rate Read rate Output + CRC ');
34
34
 
35
35
  // warmup
36
36
  if(!_.sleep) {
@@ -43,51 +43,60 @@ if(!_.sleep) {
43
43
  });
44
44
  }
45
45
 
46
+ var decCrc = function(src, raw) {
47
+ var len = y.decodeTo(src, _.bufTarget, raw);
48
+ y.crc32(_.bufTarget.slice(0, len));
49
+ };
50
+ var decIncrCrc = function(src) {
51
+ var out = y.decodeIncr(src, 0, _.bufTarget);
52
+ y.crc32(_.bufTarget.slice(0, out.written));
53
+ };
54
+
46
55
  setTimeout(function() {
47
56
  if(!_.avgOnly) {
48
57
  if(_.decMethods.clean) {
49
- _.run('Clean worst (all escaping)', y.decodeTo.bind(null, mWorst, _.bufTarget), lenWorst);
50
- _.run('Clean best (min escaping)', y.decodeTo.bind(null, mBest, _.bufTarget), lenBest);
51
- _.run('Clean pass (no escaping)', y.decodeTo.bind(null, mBest2, _.bufTarget));
58
+ _.run('Clean worst (all escaping)', y.decodeTo.bind(null, mWorst, _.bufTarget), lenWorst, decCrc.bind(null, mWorst));
59
+ _.run('Clean best (min escaping)', y.decodeTo.bind(null, mBest, _.bufTarget), lenBest, decCrc.bind(null, mBest));
60
+ _.run('Clean pass (no escaping)', y.decodeTo.bind(null, mBest2, _.bufTarget), null, decCrc.bind(null, mBest2));
52
61
  }
53
62
  if(_.decMethods.raw) {
54
- _.run('Raw worst', y.decodeTo.bind(null, mWorst, _.bufTarget, true), lenWorst);
55
- _.run('Raw best', y.decodeTo.bind(null, mBest, _.bufTarget, true), lenBest);
56
- _.run('Raw pass', y.decodeTo.bind(null, mBest2, _.bufTarget, true));
63
+ _.run('Raw worst', y.decodeTo.bind(null, mWorst, _.bufTarget, true), lenWorst, decCrc.bind(null, mWorst, true));
64
+ _.run('Raw best', y.decodeTo.bind(null, mBest, _.bufTarget, true), lenBest, decCrc.bind(null, mBest, true));
65
+ _.run('Raw pass', y.decodeTo.bind(null, mBest2, _.bufTarget, true), null, decCrc.bind(null, mBest2, true));
57
66
  }
58
67
  if(_.decMethods.rawincr) {
59
- _.run('Raw-incr worst', y.decodeIncr.bind(null, mWorst, 0, _.bufTarget), lenWorst);
60
- _.run('Raw-incr best', y.decodeIncr.bind(null, mBest, 0, _.bufTarget), lenBest);
61
- _.run('Raw-incr pass', y.decodeIncr.bind(null, mBest2, 0, _.bufTarget));
68
+ _.run('Raw-incr worst', y.decodeIncr.bind(null, mWorst, 0, _.bufTarget), lenWorst, decIncrCrc.bind(null, mWorst));
69
+ _.run('Raw-incr best', y.decodeIncr.bind(null, mBest, 0, _.bufTarget), lenBest, decIncrCrc.bind(null, mBest));
70
+ _.run('Raw-incr pass', y.decodeIncr.bind(null, mBest2, 0, _.bufTarget), null, decIncrCrc.bind(null, mBest2));
62
71
  }
63
72
  }
64
73
 
65
74
  if(_.decMethods.clean)
66
75
  mAvg.forEach(function(buf, i) {
67
- _.run('Clean random ('+i+')', y.decodeTo.bind(null, buf, _.bufTarget), lenAvg[i]);
76
+ _.run('Clean random ('+i+')', y.decodeTo.bind(null, buf, _.bufTarget), lenAvg[i], decCrc.bind(null, buf));
68
77
  });
69
78
  if(_.decMethods.raw)
70
79
  mAvg.forEach(function(buf, i) {
71
- _.run('Raw random ('+i+')', y.decodeTo.bind(null, buf, _.bufTarget, true), lenAvg[i]);
80
+ _.run('Raw random ('+i+')', y.decodeTo.bind(null, buf, _.bufTarget, true), lenAvg[i], decCrc.bind(null, buf, true));
72
81
  });
73
82
  if(_.decMethods.rawincr) {
74
83
  mAvg.forEach(function(buf, i) {
75
- _.run('Raw-incr random ('+i+')', y.decodeIncr.bind(null, buf, 0, _.bufTarget), lenAvg[i]);
84
+ _.run('Raw-incr random ('+i+')', y.decodeIncr.bind(null, buf, 0, _.bufTarget), lenAvg[i], decIncrCrc.bind(null, buf));
76
85
  });
77
86
  }
78
87
 
79
88
  if(!_.avgOnly) {
80
89
  if(_.decMethods.clean)
81
90
  mAvg2x.forEach(function(buf, i) {
82
- _.run('Clean random 2xEsc ('+i+')', y.decodeTo.bind(null, buf, _.bufTarget), lenAvg2x[i]);
91
+ _.run('Clean random 2xEsc ('+i+')', y.decodeTo.bind(null, buf, _.bufTarget), lenAvg2x[i], decCrc.bind(null, buf));
83
92
  });
84
93
  if(_.decMethods.raw)
85
94
  mAvg2x.forEach(function(buf, i) {
86
- _.run('Raw random 2xEsc ('+i+')', y.decodeTo.bind(null, buf, _.bufTarget, true), lenAvg2x[i]);
95
+ _.run('Raw random 2xEsc ('+i+')', y.decodeTo.bind(null, buf, _.bufTarget, true), lenAvg2x[i], decCrc.bind(null, buf, true));
87
96
  });
88
97
  if(_.decMethods.rawincr)
89
98
  mAvg2x.forEach(function(buf, i) {
90
- _.run('Raw-incr random 2xEsc ('+i+')', y.decodeIncr.bind(null, buf, 0, _.bufTarget), lenAvg2x[i]);
99
+ _.run('Raw-incr random 2xEsc ('+i+')', y.decodeIncr.bind(null, buf, 0, _.bufTarget), lenAvg2x[i], decIncrCrc.bind(null, buf));
91
100
  });
92
101
  }
93
102
  }, _.sleep);
package/test/speedenc.js CHANGED
@@ -5,7 +5,7 @@ var _ = require('./_speedbase');
5
5
  _.parseArgs('Syntax: node test/speedenc [-a|--average-only] [{-s|--sleep}=msecs(0)]');
6
6
 
7
7
 
8
- console.log(' Test Read rate Output rate ');
8
+ console.log(' Test Read rate Output rate Read + CRC ');
9
9
 
10
10
  var lenWorst = y.encodeTo(_.bufWorst, _.bufTarget);
11
11
  var lenBest = y.encodeTo(_.bufBest, _.bufTarget);
@@ -13,31 +13,35 @@ var lenAvg = Array(_.bufAvg.length);
13
13
  var lenAvg2x = Array(_.bufAvg2x.length);
14
14
 
15
15
  // warmup
16
- if(!_.sleep) {
17
- _.bufAvg.forEach(function(buf, i) {
18
- var p=process.hrtime();
19
- for(var j=0;j<_.rounds;j+=1) lenAvg[i] = y.encodeTo(buf, _.bufTarget);
20
- var t=process.hrtime(p);
21
- });
22
- _.bufAvg2x.forEach(function(buf, i) {
23
- var p=process.hrtime();
24
- for(var j=0;j<_.rounds;j+=1) lenAvg2x[i] = y.encodeTo(buf, _.bufTarget);
25
- var t=process.hrtime(p);
26
- });
27
- }
16
+ var initRounds = _.sleep ? 1 : _.rounds;
17
+ _.bufAvg.forEach(function(buf, i) {
18
+ var p=process.hrtime();
19
+ for(var j=0;j<initRounds;j+=1) lenAvg[i] = y.encodeTo(buf, _.bufTarget);
20
+ var t=process.hrtime(p);
21
+ });
22
+ _.bufAvg2x.forEach(function(buf, i) {
23
+ var p=process.hrtime();
24
+ for(var j=0;j<initRounds;j+=1) lenAvg2x[i] = y.encodeTo(buf, _.bufTarget);
25
+ var t=process.hrtime(p);
26
+ });
27
+
28
+ var encCrc = function(src) {
29
+ y.encodeTo(src, _.bufTarget);
30
+ y.crc32(src);
31
+ };
28
32
 
29
33
  setTimeout(function() {
30
34
  if(!_.avgOnly) {
31
- _.run('Worst (all escaping)', y.encodeTo.bind(null, _.bufWorst, _.bufTarget), lenWorst);
32
- _.run('Best (no escaping)', y.encodeTo.bind(null, _.bufBest, _.bufTarget), lenBest);
35
+ _.run('Worst (all escaping)', y.encodeTo.bind(null, _.bufWorst, _.bufTarget), lenWorst, encCrc.bind(null, _.bufWorst));
36
+ _.run('Best (no escaping)', y.encodeTo.bind(null, _.bufBest, _.bufTarget), lenBest, encCrc.bind(null, _.bufBest));
33
37
  }
34
38
 
35
39
  _.bufAvg.forEach(function(buf, i) {
36
- _.run('Random ('+i+')', y.encodeTo.bind(null, buf, _.bufTarget), lenAvg[i]);
40
+ _.run('Random ('+i+')', y.encodeTo.bind(null, buf, _.bufTarget), lenAvg[i], encCrc.bind(null, buf));
37
41
  });
38
42
  if(!_.avgOnly) {
39
43
  _.bufAvg2x.forEach(function(buf, i) {
40
- _.run('Random 2xEsc ('+i+')', y.encodeTo.bind(null, buf, _.bufTarget), lenAvg2x[i]);
44
+ _.run('Random 2xEsc ('+i+')', y.encodeTo.bind(null, buf, _.bufTarget), lenAvg2x[i], encCrc.bind(null, buf));
41
45
  });
42
46
  }
43
47
 
package/test/testcrc.js CHANGED
@@ -14,7 +14,7 @@ var ycrc32 = function(s) {
14
14
  };
15
15
  var doTest = function(msg, f, test, expected) {
16
16
  if(!Array.isArray(test)) test = [test];
17
- test[0] = Buffer(test[0]);
17
+ if(!Buffer.isBuffer(test[0])) test[0] = Buffer(test[0]);
18
18
  if(!expected && test.length == 1 && f == 'crc32') expected = crc32(test[0]).toString('hex');
19
19
  else if(Buffer.isBuffer(expected)) expected = expected.toString('hex');
20
20
  assert.equal(y[f].apply(null, test).toString('hex'), expected, msg);
@@ -45,6 +45,22 @@ assert.equal(y.crc32_zeroes(1, ycrc32('')).toString('hex'), 'd202ef8d', 'Zeroes-
45
45
  assert.equal(y.crc32_zeroes(0, ycrc32('z')).toString('hex'), crc32('z').toString('hex'), 'Zeroes Empty Join');
46
46
  assert.equal(y.crc32_zeroes(4, ycrc32('z')).toString('hex'), crc32('z\u0000\u0000\u0000\u0000').toString('hex'), 'Zeroes (4) Join');
47
47
 
48
+ assert.equal(y.crc32_zeroes(4, y.crc32_zeroes(-4)).toString('hex'), '00000000', 'Zeroes (-4+4)');
49
+ assert.equal(y.crc32_zeroes(-4, y.crc32_zeroes(4)).toString('hex'), '00000000', 'Zeroes (4-4)');
50
+ assert.equal(y.crc32_zeroes(6, y.crc32_zeroes(-2, ycrc32('z'))).toString('hex'), crc32('z\u0000\u0000\u0000\u0000').toString('hex'), 'Zeroes (-2+6) Join');
51
+
52
+
53
+ assert.equal(y.crc32_multiply(Buffer([1,2,3,4]), ycrc32('')).toString('hex'), '00000000', 'Multiply by 0');
54
+ assert.equal(y.crc32_multiply(Buffer([0x80,0,0,0]), Buffer([0x80,0,0,0])).toString('hex'), '80000000', 'Multiply by 1');
55
+ assert.equal(y.crc32_multiply(Buffer([1,2,3,4]), Buffer([5,6,7,8])).toString('hex'), '81e243a3', 'Multiply random');
56
+
57
+ assert.equal(y.crc32_shift(0).toString('hex'), '80000000', '2^0');
58
+ assert.equal(y.crc32_shift(1).toString('hex'), '40000000', '2^1');
59
+ assert.equal(y.crc32_shift(2).toString('hex'), '20000000', '2^2');
60
+ assert.equal(y.crc32_shift(-1).toString('hex'), 'db710641', '2^-1');
61
+ assert.equal(y.crc32_shift(-1, y.crc32_shift(1)).toString('hex'), '80000000', '2^(1-1)');
62
+ assert.equal(y.crc32_shift(4, y.crc32_shift(-2)).toString('hex'), '20000000', '2^(-2+4)');
63
+
48
64
 
49
65
  doTest('Random', 'crc32', 'fj[-oqijnw34-59n26 4345j8yn89032q78t9ab9gabh023quhoiBO Z GEB780a sdasdq2345673-98hq2-9348h-na9we8zdfgh-n9 8qwhn-098');
50
66
  doTest('Random Continue', 'crc32', ['KZSHZ5EDOVAmDdakZZOrGSUGGKSpCJoWH7M0MHy6ohnSzvHY4DjpxXmyfWYJQoJ7tKdNhGcuRVUzrgXM', ycrc32('BdenbmoBgiB10ZkeUBjrsZV3dg2Da2fhHqU9TMdi69AHhLRck3Nk60YuFBXh6lvtefBpjdTxbeEmsaEm')], crc32('BdenbmoBgiB10ZkeUBjrsZV3dg2Da2fhHqU9TMdi69AHhLRck3Nk60YuFBXh6lvtefBpjdTxbeEmsaEmKZSHZ5EDOVAmDdakZZOrGSUGGKSpCJoWH7M0MHy6ohnSzvHY4DjpxXmyfWYJQoJ7tKdNhGcuRVUzrgXM'));
@@ -0,0 +1,53 @@
1
+ // compile with: c++ -O -DYENC_DISABLE_CRCUTIL=1 testcrcfuncs.c ../src/crc.cc ../src/crc_*.cc ../src/platform.cc -o testcrcfuncs
2
+
3
+ #include <stdint.h>
4
+ #include <stddef.h>
5
+ #include "../src/crc.h"
6
+ #include <assert.h>
7
+
8
+ int main(void) {
9
+ crc_init();
10
+
11
+ // test crc32_bytepow
12
+
13
+ assert(crc32_bytepow(0) == 0);
14
+ assert(crc32_bytepow(1) == 8);
15
+ assert(crc32_bytepow(2) == 16);
16
+ assert(crc32_bytepow((1<<29)-1) == 0xfffffff8);
17
+ assert(crc32_bytepow(1<<29) == 1);
18
+ assert(crc32_bytepow((1<<29)+1) == 9);
19
+
20
+ uint32_t actual;
21
+ // just do an exhaustive search, since it's not that slow
22
+ for(uint64_t i=1<<29; i<((1ULL<<32) + 256); i++) {
23
+ uint32_t ref = (i*8) % 0xffffffff;
24
+ actual = crc32_bytepow(i);
25
+ if(ref == 0)
26
+ assert(actual == 0 || actual == 0xffffffff);
27
+ else
28
+ assert(ref == actual);
29
+ }
30
+
31
+ assert(crc32_bytepow(1ULL<<60) == 0x80000000);
32
+ assert(crc32_bytepow(1ULL<<61) == 1);
33
+ assert(crc32_bytepow(1ULL<<62) == 2);
34
+ assert(crc32_bytepow(1ULL<<63) == 4);
35
+ actual = crc32_bytepow(~0ULL);
36
+ assert(actual == 0 || actual == 0xffffffff);
37
+ assert(crc32_bytepow(~0ULL -1) == 0xfffffff7);
38
+ assert(crc32_bytepow((1ULL<<63) -1) == 0xfffffffb);
39
+ assert(crc32_bytepow((1ULL<<63) +1) == 12);
40
+
41
+
42
+ // test crc32_mul2pow
43
+ assert(crc32_mul2pow(0, 0) == 0);
44
+ assert(crc32_mul2pow(0, 1) == 1);
45
+ assert(crc32_mul2pow(1, 0) == 0);
46
+ assert(crc32_mul2pow(1, 0x80000000) == 0x40000000);
47
+ assert(crc32_mul2pow(1, 0x40000000) == 0x20000000);
48
+ assert(crc32_mul2pow(4, 0x80000000) == 0x08000000);
49
+ assert(crc32_mul2pow(5, 0x80000000) == 0x04000000);
50
+ assert(crc32_mul2pow(0xffffffff, 123) == 123);
51
+
52
+ return 0;
53
+ }
package/test/testdec.js CHANGED
@@ -114,6 +114,7 @@ var doTest = function(msg, data, expected) {
114
114
  if(actual != x) {
115
115
  console.log('Actual:', actual);
116
116
  console.log('Expect:', x);
117
+ console.log('Source:', data.toString('hex'));
117
118
  assert.equal(actual, x, msg + ' (in-situ) [' + i + '/' + j + ' ' + f.l + ']');
118
119
  }
119
120
  });