yencode 1.1.4 → 1.2.0

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.
package/src/encoder.h CHANGED
@@ -10,8 +10,12 @@ extern "C" {
10
10
  #include "hedley.h"
11
11
 
12
12
  extern size_t (*_do_encode)(int, int*, const unsigned char* HEDLEY_RESTRICT, unsigned char* HEDLEY_RESTRICT, size_t, int);
13
+ extern int _encode_isa;
13
14
  #define do_encode (*_do_encode)
14
15
  void encoder_init();
16
+ static inline int encode_isa_level() {
17
+ return _encode_isa;
18
+ }
15
19
 
16
20
 
17
21
 
@@ -6,6 +6,7 @@
6
6
  void encoder_avx_init() {
7
7
  _do_encode = &do_encode_simd< do_encode_sse<ISA_LEVEL_SSE4_POPCNT> >;
8
8
  encoder_sse_lut<ISA_LEVEL_SSE4_POPCNT>();
9
+ _encode_isa = ISA_LEVEL_AVX;
9
10
  }
10
11
  #else
11
12
  void encoder_ssse3_init();
@@ -6,6 +6,7 @@
6
6
  void encoder_avx2_init() {
7
7
  _do_encode = &do_encode_simd< do_encode_avx2<ISA_LEVEL_AVX2> >;
8
8
  encoder_avx2_lut<ISA_LEVEL_AVX2>();
9
+ _encode_isa = ISA_LEVEL_AVX2;
9
10
  }
10
11
  #else
11
12
  void encoder_avx_init();
@@ -2,26 +2,8 @@
2
2
  #define __YENC_ENCODER_COMMON
3
3
 
4
4
  // lookup tables for scalar processing
5
- #define _B1(n) _B(n), _B(n+1), _B(n+2), _B(n+3)
6
- #define _B2(n) _B1(n), _B1(n+4), _B1(n+8), _B1(n+12)
7
- #define _B3(n) _B2(n), _B2(n+16), _B2(n+32), _B2(n+48)
8
- #define _BX _B3(0), _B3(64), _B3(128), _B3(192)
9
-
10
- static const unsigned char escapeLUT[256] = { // whether or not the character is critical
11
- #define _B(n) ((n == 214 || n == '\r'+214 || n == '\n'+214 || n == '='-42) ? 0 : (n+42) & 0xff)
12
- _BX
13
- #undef _B
14
- };
15
- static const uint16_t escapedLUT[256] = { // escaped sequences for characters that need escaping
16
- #define _B(n) ((n == 214 || n == 214+'\r' || n == 214+'\n' || n == '='-42 || n == 214+'\t' || n == 214+' ' || n == '.'-42) ? UINT16_PACK('=', ((n+42+64)&0xff)) : 0)
17
- _BX
18
- #undef _B
19
- };
20
-
21
- #undef _B1
22
- #undef _B2
23
- #undef _B3
24
- #undef _BX
5
+ extern const unsigned char escapeLUT[256];
6
+ extern const uint16_t escapedLUT[256];
25
7
 
26
8
 
27
9
  size_t do_encode_generic(int line_size, int* colOffset, const unsigned char* HEDLEY_RESTRICT src, unsigned char* HEDLEY_RESTRICT dest, size_t len, int doEnd);
@@ -520,6 +520,7 @@ HEDLEY_ALWAYS_INLINE void do_encode_neon(int line_size, int* colOffset, const ui
520
520
 
521
521
  void encoder_neon_init() {
522
522
  _do_encode = &do_encode_simd<do_encode_neon>;
523
+ _encode_isa = ISA_LEVEL_NEON;
523
524
  // generate shuf LUT
524
525
  for(int i=0; i<256; i++) {
525
526
  int k = i;
@@ -4,13 +4,6 @@
4
4
  #include "encoder.h"
5
5
  #include "encoder_common.h"
6
6
 
7
- # include <riscv_vector.h>
8
- # if defined(__clang__) && __clang_major__ < 16
9
- # define RV(f) f
10
- # else
11
- # define RV(f) __riscv_##f
12
- # endif
13
-
14
7
 
15
8
  static HEDLEY_ALWAYS_INLINE void encode_eol_handle_pre(const uint8_t* HEDLEY_RESTRICT _src, long& inpos, uint8_t*& outp, long& col, long lineSizeOffset) {
16
9
  // TODO: vectorize
@@ -112,7 +105,7 @@ HEDLEY_ALWAYS_INLINE void do_encode_rvv(int line_size, int* colOffset, const uin
112
105
  vl2
113
106
  );
114
107
 
115
- #if defined(__riscv_v_intrinsic) && __riscv_v_intrinsic >= 13000
108
+ #ifdef __riscv_v_intrinsic
116
109
  data = RV(vor_vx_u8m2_mu)(cmp, tmpData, tmpData, 64, vl2);
117
110
  #else
118
111
  data = RV(vor_vx_u8m2_m)(cmp, tmpData, tmpData, 64, vl2);
@@ -122,11 +115,7 @@ HEDLEY_ALWAYS_INLINE void do_encode_rvv(int line_size, int* colOffset, const uin
122
115
  size_t count = RV(vcpop_m_b4)(cmp, vl2);
123
116
  if(count > 1) {
124
117
  // widen mask: 4b->8b
125
- #if defined(__riscv_v_intrinsic) && __riscv_v_intrinsic >= 13000
126
- vuint8mf4_t vcmp = RV(vlmul_trunc_v_u8m1_u8mf4)(RV(vreinterpret_v_b4_u8m1)(cmp));
127
- #else
128
- vuint8mf4_t vcmp = *(vuint8mf4_t*)(&cmp);
129
- #endif
118
+ vuint8mf4_t vcmp = RV_VEC_U8MF4_CAST(cmp);
130
119
  // TODO: use vwsll instead if available
131
120
  // - is clmul useful here?
132
121
  vuint8mf2_t xcmp = RV(vreinterpret_v_u16mf2_u8mf2)(RV(vwmulu_vx_u16mf2)(vcmp, 16, vl2));
@@ -134,11 +123,7 @@ HEDLEY_ALWAYS_INLINE void do_encode_rvv(int line_size, int* colOffset, const uin
134
123
 
135
124
  // expand mask by inserting '1' between each bit (0000abcd -> 1a1b1c1d)
136
125
  vuint8m1_t xcmpTmp = RV(vrgather_vv_u8m1)(MASK_EXPAND, RV(vlmul_ext_v_u8mf2_u8m1)(xcmp), vl2);
137
- #if defined(__riscv_v_intrinsic) && __riscv_v_intrinsic >= 13000
138
- vbool2_t cmpmask = RV(vreinterpret_b2)(xcmpTmp);
139
- #else
140
- vbool2_t cmpmask = *(vbool2_t*)(&xcmpTmp);
141
- #endif
126
+ vbool2_t cmpmask = RV_MASK_CAST(2, 8, xcmpTmp);
142
127
 
143
128
  // expand data and insert =
144
129
  // TODO: use vwsll instead if available
@@ -149,7 +134,7 @@ HEDLEY_ALWAYS_INLINE void do_encode_rvv(int line_size, int* colOffset, const uin
149
134
  // prune unneeded =
150
135
  vuint8m4_t dataTmp = RV(vreinterpret_v_u16m4_u8m4)(data2);
151
136
  vuint8m4_t final_data = RV(vcompress_vm_u8m4)(
152
- #if defined(__riscv_v_intrinsic) && __riscv_v_intrinsic >= 13000
137
+ #ifdef __riscv_v_intrinsic
153
138
  dataTmp, cmpmask, vl2*2
154
139
  #else
155
140
  cmpmask, dataTmp, dataTmp, vl2*2
@@ -213,6 +198,7 @@ HEDLEY_ALWAYS_INLINE void do_encode_rvv(int line_size, int* colOffset, const uin
213
198
 
214
199
  void encoder_rvv_init() {
215
200
  _do_encode = &do_encode_simd<do_encode_rvv>;
201
+ _encode_isa = ISA_LEVEL_RVV;
216
202
  }
217
203
  #else
218
204
  void encoder_rvv_init() {}
@@ -6,6 +6,7 @@
6
6
  void encoder_sse2_init() {
7
7
  _do_encode = &do_encode_simd< do_encode_sse<ISA_LEVEL_SSE2> >;
8
8
  encoder_sse_lut<ISA_LEVEL_SSE2>();
9
+ _encode_isa = ISA_LEVEL_SSE2;
9
10
  }
10
11
  #else
11
12
  void encoder_sse2_init() {}
@@ -8,6 +8,7 @@
8
8
  void encoder_ssse3_init() {
9
9
  _do_encode = &do_encode_simd< do_encode_sse<ISA_LEVEL_SSSE3> >;
10
10
  encoder_sse_lut<ISA_LEVEL_SSSE3>();
11
+ _encode_isa = ISA_LEVEL_SSSE3;
11
12
  }
12
13
  #else
13
14
  void encoder_sse2_init();
@@ -14,12 +14,14 @@ const bool encoder_has_avx10 = false;
14
14
  void encoder_vbmi2_init() {
15
15
  _do_encode = &do_encode_simd< do_encode_avx2<ISA_LEVEL_VBMI2> >;
16
16
  encoder_avx2_lut<ISA_LEVEL_VBMI2>();
17
+ _encode_isa = ISA_LEVEL_VBMI2;
17
18
  }
18
19
  # else
19
20
  # include "encoder_sse_base.h"
20
21
  void encoder_vbmi2_init() {
21
22
  _do_encode = &do_encode_simd< do_encode_sse<ISA_LEVEL_VBMI2> >;
22
23
  encoder_sse_lut<ISA_LEVEL_VBMI2>();
24
+ _encode_isa = ISA_LEVEL_VBMI2;
23
25
  }
24
26
  # endif
25
27
  #else
package/src/platform.cc CHANGED
@@ -138,14 +138,14 @@ int cpu_supports_isa() {
138
138
  _cpuidX(cpuInfo2, 7, 1);
139
139
  if(cpuInfo2[3] & 0x80000) {
140
140
  _cpuidX(cpuInfo2, 0x24, 0);
141
- if((cpuInfo2[2] & 0xff) >= 1 && ( // minimum AVX10.1
141
+ if((cpuInfo2[1] & 0xff) >= 1 && ( // minimum AVX10.1
142
142
  #ifdef YENC_DISABLE_AVX256
143
- cpuInfo2[2] & 0x10000 // AVX10/128
143
+ cpuInfo2[1] & 0x10000 // AVX10/128
144
144
  #else
145
- cpuInfo2[2] & 0x20000 // AVX10/256
145
+ cpuInfo2[1] & 0x20000 // AVX10/256
146
146
  #endif
147
147
  )) {
148
- if(((xcr & 0xE0) == 0xE0) && (cpuInfo2[2] & 0x40000)) ret |= ISA_FEATURE_EVEX512;
148
+ if(((xcr & 0xE0) == 0xE0) && (cpuInfo2[1] & 0x40000)) ret |= ISA_FEATURE_EVEX512;
149
149
  return ret | ISA_LEVEL_VBMI2;
150
150
  }
151
151
  }
package/src/yencode.cc CHANGED
@@ -383,7 +383,7 @@ FUNC(CRC32Combine) {
383
383
  uint32_t crc1 = read_crc32(args[0]), crc2 = read_crc32(args[1]);
384
384
  size_t len = (size_t)ARG_TO_INT(args[2]);
385
385
 
386
- crc1 = do_crc32_combine(crc1, crc2, len);
386
+ crc1 = crc32_combine(crc1, crc2, len);
387
387
  RETURN_VAL(pack_crc32(ISOLATE crc1));
388
388
  }
389
389
 
@@ -399,11 +399,51 @@ FUNC(CRC32Zeroes) {
399
399
  RETURN_ERROR("Second argument must be a 4 byte buffer");
400
400
  crc1 = read_crc32(args[1]);
401
401
  }
402
- size_t len = (size_t)ARG_TO_INT(args[0]);
403
- crc1 = do_crc32_zeros(crc1, len);
402
+ int len = ARG_TO_INT(args[0]);
403
+ if(len < 0)
404
+ crc1 = crc32_unzero(crc1, -len);
405
+ else
406
+ crc1 = crc32_zeros(crc1, len);
404
407
  RETURN_VAL(pack_crc32(ISOLATE crc1));
405
408
  }
406
409
 
410
+ FUNC(CRC32Multiply) {
411
+ FUNC_START;
412
+
413
+ if (args.Length() < 2)
414
+ RETURN_ERROR("At least 2 arguments required");
415
+
416
+ if (!node::Buffer::HasInstance(args[0]) || node::Buffer::Length(args[0]) != 4
417
+ || !node::Buffer::HasInstance(args[1]) || node::Buffer::Length(args[1]) != 4)
418
+ RETURN_ERROR("You must supply a 4 byte Buffer for the first two arguments");
419
+
420
+ uint32_t crc1 = read_crc32(args[0]);
421
+ uint32_t crc2 = read_crc32(args[1]);
422
+ crc1 = crc32_multiply(crc1, crc2);
423
+ RETURN_VAL(pack_crc32(ISOLATE crc1));
424
+ }
425
+
426
+ FUNC(CRC32Shift) {
427
+ FUNC_START;
428
+
429
+ if (args.Length() < 1)
430
+ RETURN_ERROR("At least 1 argument required");
431
+
432
+ uint32_t crc1 = 0x80000000;
433
+ if (args.Length() >= 2) {
434
+ if (!node::Buffer::HasInstance(args[1]) || node::Buffer::Length(args[1]) != 4)
435
+ RETURN_ERROR("Second argument must be a 4 byte buffer");
436
+ crc1 = read_crc32(args[1]);
437
+ }
438
+ int n = ARG_TO_INT(args[0]);
439
+ if(n < 0)
440
+ crc1 = crc32_shift(crc1, ~crc32_powmod(-n));
441
+ else
442
+ crc1 = crc32_shift(crc1, crc32_powmod(n));
443
+ RETURN_VAL(pack_crc32(ISOLATE crc1));
444
+ }
445
+
446
+
407
447
  static void init_all() {
408
448
  encoder_init();
409
449
  decoder_init();
@@ -436,6 +476,8 @@ void yencode_init(
436
476
  NODE_SET_METHOD(exports, "crc32", CRC32);
437
477
  NODE_SET_METHOD(exports, "crc32_combine", CRC32Combine);
438
478
  NODE_SET_METHOD(exports, "crc32_zeroes", CRC32Zeroes);
479
+ NODE_SET_METHOD(exports, "crc32_multiply", CRC32Multiply);
480
+ NODE_SET_METHOD(exports, "crc32_shift", CRC32Shift);
439
481
 
440
482
  #if NODE_VERSION_AT_LEAST(10, 7, 0)
441
483
  uv_once(&init_once, init_all);
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'));
@@ -52,11 +68,11 @@ doTest('Random Continue', 'crc32', ['KZSHZ5EDOVAmDdakZZOrGSUGGKSpCJoWH7M0MHy6ohn
52
68
 
53
69
  // random tests
54
70
  for(var i=1; i<128; i++) {
55
- var rand = require('crypto').pseudoRandomBytes(i);
71
+ var rand = Buffer(require('crypto').randomBytes(i)); // Bun needs explicit Buffer for pseudoRandomBytes
56
72
  doTest('Random Short Buffer', 'crc32', rand);
57
73
  }
58
74
  for(var i=0; i<32; i++) {
59
- var rand = require('crypto').pseudoRandomBytes(100000);
75
+ var rand = Buffer(require('crypto').randomBytes(100000));
60
76
  doTest('Random Buffer', 'crc32', rand);
61
77
 
62
78
  var split = Math.random()*rand.length;
@@ -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
  });
@@ -177,7 +178,7 @@ doTest('Extra null issue', toBuffer('2e900a4fb6054c9126171cdc196dc41237bb1b76da9
177
178
 
178
179
  // random tests
179
180
  for(var i=0; i<32; i++) {
180
- var rand = require('crypto').pseudoRandomBytes(128*1024);
181
+ var rand = require('crypto').randomBytes(128*1024);
181
182
  doTest('Random', rand);
182
183
  }
183
184
 
package/test/testenc.js CHANGED
@@ -141,7 +141,7 @@ padding.fill(97); // 'a'
141
141
 
142
142
  // random tests
143
143
  for(var i=0; i<32; i++) {
144
- var rand = require('crypto').pseudoRandomBytes(4*1024);
144
+ var rand = require('crypto').randomBytes(4*1024);
145
145
  runLineSizes(function(ls, offs) {
146
146
  doTest('Random [ls='+ls+', offs='+offs+']', [rand, ls, offs]);
147
147
  });