yencode 1.1.2 → 1.1.4
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/README.md +3 -2
- package/binding.gyp +141 -6
- package/index.js +21 -19
- package/package.json +2 -1
- package/src/common.h +34 -19
- package/src/crc.cc +138 -11
- package/src/crc_arm.cc +42 -7
- package/src/crc_folding.cc +18 -53
- package/src/crc_folding_256.cc +229 -0
- package/src/decoder.cc +8 -4
- package/src/decoder.h +5 -5
- package/src/decoder_avx2_base.h +30 -13
- package/src/decoder_common.h +5 -5
- package/src/decoder_neon.cc +4 -4
- package/src/decoder_neon64.cc +10 -7
- package/src/decoder_sse_base.h +26 -12
- package/src/decoder_vbmi2.cc +37 -0
- package/src/encoder.cc +10 -1
- package/src/encoder_avx_base.h +24 -16
- package/src/encoder_neon.cc +40 -41
- package/src/encoder_rvv.cc +219 -0
- package/src/encoder_sse_base.h +7 -8
- package/src/encoder_vbmi2.cc +30 -0
- package/src/hedley.h +278 -135
- package/src/platform.cc +79 -10
- package/src/test_alignalloc.c +6 -0
- package/test/_speedbase.js +12 -11
- package/test/speeddec.js +6 -5
- package/test/testcrc.js +14 -0
- package/test/testdec.js +30 -14
- package/test/testenc.js +10 -7
- package/test/testpostdec.js +6 -5
package/src/platform.cc
CHANGED
|
@@ -2,12 +2,6 @@
|
|
|
2
2
|
#ifdef PLATFORM_ARM
|
|
3
3
|
# ifdef __ANDROID__
|
|
4
4
|
# include <cpu-features.h>
|
|
5
|
-
# elif defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 12)
|
|
6
|
-
# include <sys/auxv.h>
|
|
7
|
-
# include <asm/hwcap.h>
|
|
8
|
-
# elif (defined(__FreeBSD__) && __FreeBSD__ < 12)
|
|
9
|
-
# include <sys/sysctl.h>
|
|
10
|
-
# include <asm/hwcap.h>
|
|
11
5
|
# elif defined(_WIN32)
|
|
12
6
|
# define WIN32_LEAN_AND_MEAN
|
|
13
7
|
# define NOMINMAX
|
|
@@ -15,6 +9,13 @@
|
|
|
15
9
|
# elif defined(__APPLE__)
|
|
16
10
|
# include <sys/types.h>
|
|
17
11
|
# include <sys/sysctl.h>
|
|
12
|
+
# elif defined(__has_include)
|
|
13
|
+
# if __has_include(<sys/auxv.h>)
|
|
14
|
+
# include <sys/auxv.h>
|
|
15
|
+
# if __has_include(<asm/hwcap.h>)
|
|
16
|
+
# include <asm/hwcap.h>
|
|
17
|
+
# endif
|
|
18
|
+
# endif
|
|
18
19
|
# endif
|
|
19
20
|
bool cpu_supports_neon() {
|
|
20
21
|
# if defined(AT_HWCAP)
|
|
@@ -48,13 +49,18 @@ bool cpu_supports_neon() {
|
|
|
48
49
|
return false;
|
|
49
50
|
return (bool)supported;
|
|
50
51
|
# endif
|
|
51
|
-
|
|
52
|
+
# ifdef __aarch64__
|
|
53
|
+
return true; // assume NEON support on AArch64
|
|
54
|
+
# else
|
|
55
|
+
return false;
|
|
56
|
+
# endif
|
|
52
57
|
}
|
|
53
58
|
#endif
|
|
54
59
|
|
|
55
60
|
|
|
56
61
|
#ifdef PLATFORM_X86
|
|
57
62
|
#ifdef _MSC_VER
|
|
63
|
+
# define _cpuid1(ar) __cpuid(ar, 1)
|
|
58
64
|
# define _cpuid1x(ar) __cpuid(ar, 0x80000001)
|
|
59
65
|
# if _MSC_VER >= 1600
|
|
60
66
|
# define _cpuidX __cpuidex
|
|
@@ -66,6 +72,8 @@ bool cpu_supports_neon() {
|
|
|
66
72
|
# define _GET_XCR() 0
|
|
67
73
|
# endif
|
|
68
74
|
#else
|
|
75
|
+
# include <cpuid.h>
|
|
76
|
+
# define _cpuid1(ar) __cpuid(1, ar[0], ar[1], ar[2], ar[3])
|
|
69
77
|
# define _cpuid1x(ar) __cpuid(0x80000001, ar[0], ar[1], ar[2], ar[3])
|
|
70
78
|
# define _cpuidX(ar, eax, ecx) __cpuid_count(eax, ecx, ar[0], ar[1], ar[2], ar[3])
|
|
71
79
|
static inline int _GET_XCR() {
|
|
@@ -112,21 +120,38 @@ int cpu_supports_isa() {
|
|
|
112
120
|
// AMD Bobcat with slow SSSE3 instructions - pretend it doesn't exist
|
|
113
121
|
return ret | ISA_LEVEL_SSE2;
|
|
114
122
|
|
|
115
|
-
// Jaguar/Puma performance unkown (slowish PSHUFB/PBLENDVB)
|
|
116
|
-
|
|
117
123
|
if((flags[2] & 0x200) == 0x200) { // SSSE3
|
|
118
124
|
if(family == 6 && (model == 0x5c || model == 0x5f || model == 0x7a || model == 0x9c))
|
|
119
125
|
// Intel Goldmont/plus / Tremont with slow PBLENDVB
|
|
120
126
|
return ret | ISA_LEVEL_SSSE3;
|
|
121
127
|
|
|
122
128
|
if(flags[2] & 0x80000) { // SSE4.1
|
|
123
|
-
if((flags[2] &
|
|
129
|
+
if((flags[2] & 0x1C800000) == 0x1C800000) { // POPCNT + OSXSAVE + XSAVE + AVX
|
|
124
130
|
int xcr = _GET_XCR() & 0xff; // ignore unused bits
|
|
125
131
|
if((xcr & 6) == 6) { // AVX enabled
|
|
126
132
|
int cpuInfo[4];
|
|
127
133
|
_cpuidX(cpuInfo, 7, 0);
|
|
128
134
|
if((cpuInfo[1] & 0x128) == 0x128 && (ret & ISA_FEATURE_LZCNT)) { // BMI2 + AVX2 + BMI1
|
|
135
|
+
|
|
136
|
+
// check AVX10
|
|
137
|
+
int cpuInfo2[4];
|
|
138
|
+
_cpuidX(cpuInfo2, 7, 1);
|
|
139
|
+
if(cpuInfo2[3] & 0x80000) {
|
|
140
|
+
_cpuidX(cpuInfo2, 0x24, 0);
|
|
141
|
+
if((cpuInfo2[2] & 0xff) >= 1 && ( // minimum AVX10.1
|
|
142
|
+
#ifdef YENC_DISABLE_AVX256
|
|
143
|
+
cpuInfo2[2] & 0x10000 // AVX10/128
|
|
144
|
+
#else
|
|
145
|
+
cpuInfo2[2] & 0x20000 // AVX10/256
|
|
146
|
+
#endif
|
|
147
|
+
)) {
|
|
148
|
+
if(((xcr & 0xE0) == 0xE0) && (cpuInfo2[2] & 0x40000)) ret |= ISA_FEATURE_EVEX512;
|
|
149
|
+
return ret | ISA_LEVEL_VBMI2;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
129
153
|
if(((xcr & 0xE0) == 0xE0) && (cpuInfo[1] & 0xC0010000) == 0xC0010000) { // AVX512BW + AVX512VL + AVX512F
|
|
154
|
+
ret |= ISA_FEATURE_EVEX512;
|
|
130
155
|
if(cpuInfo[2] & 0x40)
|
|
131
156
|
return ret | ISA_LEVEL_VBMI2;
|
|
132
157
|
return ret | ISA_LEVEL_AVX3;
|
|
@@ -144,4 +169,48 @@ int cpu_supports_isa() {
|
|
|
144
169
|
return ret | ISA_LEVEL_SSE2;
|
|
145
170
|
}
|
|
146
171
|
|
|
172
|
+
int cpu_supports_crc_isa() {
|
|
173
|
+
int flags[4];
|
|
174
|
+
_cpuid1(flags);
|
|
175
|
+
|
|
176
|
+
if((flags[2] & 0x80202) == 0x80202) { // SSE4.1 + SSSE3 + CLMUL
|
|
177
|
+
if((flags[2] & 0x1C000000) == 0x1C000000) { // AVX + OSXSAVE + XSAVE
|
|
178
|
+
int xcr = _GET_XCR() & 0xff; // ignore unused bits
|
|
179
|
+
if((xcr & 6) == 6) { // AVX enabled
|
|
180
|
+
int cpuInfo[4];
|
|
181
|
+
_cpuidX(cpuInfo, 7, 0);
|
|
182
|
+
if((cpuInfo[1] & 0x20) == 0x20 && (cpuInfo[2] & 0x400) == 0x400) { // AVX2 + VPCLMULQDQ
|
|
183
|
+
return 2;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return 1;
|
|
188
|
+
}
|
|
189
|
+
return 0;
|
|
190
|
+
}
|
|
191
|
+
|
|
147
192
|
#endif // PLATFORM_X86
|
|
193
|
+
|
|
194
|
+
#ifdef __riscv
|
|
195
|
+
# if defined(__has_include)
|
|
196
|
+
# if __has_include(<sys/auxv.h>)
|
|
197
|
+
# include <sys/auxv.h>
|
|
198
|
+
# if __has_include(<asm/hwcap.h>)
|
|
199
|
+
# include <asm/hwcap.h>
|
|
200
|
+
# endif
|
|
201
|
+
# endif
|
|
202
|
+
# endif
|
|
203
|
+
bool cpu_supports_rvv() {
|
|
204
|
+
# if defined(AT_HWCAP)
|
|
205
|
+
unsigned long ret;
|
|
206
|
+
# ifdef __FreeBSD__
|
|
207
|
+
elf_aux_info(AT_HWCAP, &ret, sizeof(ret));
|
|
208
|
+
# else
|
|
209
|
+
ret = getauxval(AT_HWCAP);
|
|
210
|
+
# endif
|
|
211
|
+
return (ret & 0x20112D) == 0x20112D; // IMAFDCV; TODO: how to detect Z* features of 'G'?
|
|
212
|
+
# endif
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
#endif
|
|
216
|
+
|
package/test/_speedbase.js
CHANGED
|
@@ -5,31 +5,32 @@ var trials = 8;
|
|
|
5
5
|
var asyncWait = 1000;
|
|
6
6
|
|
|
7
7
|
var maxSize = require('./_maxsize');
|
|
8
|
-
var
|
|
8
|
+
var allocBuffer = (Buffer.allocUnsafe || Buffer);
|
|
9
|
+
var decimal = (''+1.1).substring(1, 2);
|
|
9
10
|
var fmtSpeed = function(size, time) {
|
|
10
11
|
var rate = ('' + (Math.round(100*(size/1048576)/time)/100)).split(decimal);
|
|
11
12
|
|
|
12
|
-
return (' ' + rate[0]).
|
|
13
|
+
return (' ' + rate[0]).slice(-8) + decimal + ((rate[1]|0) + '00').substring(0, 2) + ' MiB/s';
|
|
13
14
|
};
|
|
14
15
|
var initBuffers = function() {
|
|
15
|
-
module.exports.bufWorst =
|
|
16
|
-
module.exports.bufBest =
|
|
16
|
+
module.exports.bufWorst = allocBuffer(sz);
|
|
17
|
+
module.exports.bufBest = allocBuffer(sz);
|
|
17
18
|
module.exports.bufAvg = [];
|
|
18
19
|
module.exports.bufAvg2x = [];
|
|
19
|
-
module.exports.bufTarget =
|
|
20
|
+
module.exports.bufTarget = allocBuffer(maxSize(sz));
|
|
20
21
|
|
|
21
22
|
module.exports.bufWorst.fill(224);
|
|
22
23
|
module.exports.bufBest.fill(0);
|
|
23
24
|
|
|
24
25
|
// use cipher as a fast, consistent RNG
|
|
25
|
-
var cipher = require('crypto').
|
|
26
|
-
[['aes-128-cbc', '
|
|
27
|
-
['
|
|
28
|
-
['aes-128-cbc', '
|
|
26
|
+
var cipher = require('crypto').createCipheriv;
|
|
27
|
+
[['aes-128-cbc', 'my_incredible_pw', ' '],
|
|
28
|
+
['aes-128-cbc', 'nfa807g2lablzxk1', ' '],
|
|
29
|
+
['aes-128-cbc', '3h89sdg923jnkbas', ' ']
|
|
29
30
|
].forEach(function(cargs) {
|
|
30
31
|
var rand = cipher.apply(null, cargs);
|
|
31
32
|
var data = Buffer.concat([rand.update(module.exports.bufBest), rand.final()]).slice(0, sz);
|
|
32
|
-
module.exports.bufAvg.push(
|
|
33
|
+
module.exports.bufAvg.push(Buffer.concat([data]));
|
|
33
34
|
|
|
34
35
|
// all yEnc special characters exist in range 0-61 (post shift) or 214-19 (pre-shift)
|
|
35
36
|
// to generate biased data, we'll pack the range down (64-191 will get packed to 192-63)
|
|
@@ -83,7 +84,7 @@ module.exports = {
|
|
|
83
84
|
run: function(name, fn, sz2) {
|
|
84
85
|
var time = module.exports.bench(fn);
|
|
85
86
|
console.log(
|
|
86
|
-
(name+' ').
|
|
87
|
+
(name+' ').substring(0, 25) + ':'
|
|
87
88
|
+ fmtSpeed(sz*rounds, time)
|
|
88
89
|
+ (sz2 ? (' ' + fmtSpeed(sz2*rounds, time)) : '')
|
|
89
90
|
);
|
package/test/speeddec.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
var y = require('../build/Release/yencode');
|
|
2
2
|
var _ = require('./_speedbase');
|
|
3
|
+
var allocBuffer = (Buffer.allocUnsafe || Buffer);
|
|
3
4
|
|
|
4
5
|
var bufSize = _.bufTarget.length;
|
|
5
6
|
|
|
6
|
-
var mWorst =
|
|
7
|
+
var mWorst = allocBuffer(bufSize);
|
|
7
8
|
var mAvg = _.bufAvg.map(function() {
|
|
8
|
-
return
|
|
9
|
+
return allocBuffer(bufSize);
|
|
9
10
|
});
|
|
10
11
|
var mAvg2x = _.bufAvg2x.map(function() {
|
|
11
|
-
return
|
|
12
|
+
return allocBuffer(bufSize);
|
|
12
13
|
});
|
|
13
|
-
var mBest =
|
|
14
|
-
var mBest2 =
|
|
14
|
+
var mBest = allocBuffer(bufSize);
|
|
15
|
+
var mBest2 = allocBuffer(_.size);
|
|
15
16
|
mBest2.fill(32);
|
|
16
17
|
|
|
17
18
|
var lenWorst = y.encodeTo(_.bufWorst, mWorst);
|
package/test/testcrc.js
CHANGED
|
@@ -50,4 +50,18 @@ doTest('Random', 'crc32', 'fj[-oqijnw34-59n26 4345j8yn89032q78t9ab9gabh023quhoiB
|
|
|
50
50
|
doTest('Random Continue', 'crc32', ['KZSHZ5EDOVAmDdakZZOrGSUGGKSpCJoWH7M0MHy6ohnSzvHY4DjpxXmyfWYJQoJ7tKdNhGcuRVUzrgXM', ycrc32('BdenbmoBgiB10ZkeUBjrsZV3dg2Da2fhHqU9TMdi69AHhLRck3Nk60YuFBXh6lvtefBpjdTxbeEmsaEm')], crc32('BdenbmoBgiB10ZkeUBjrsZV3dg2Da2fhHqU9TMdi69AHhLRck3Nk60YuFBXh6lvtefBpjdTxbeEmsaEmKZSHZ5EDOVAmDdakZZOrGSUGGKSpCJoWH7M0MHy6ohnSzvHY4DjpxXmyfWYJQoJ7tKdNhGcuRVUzrgXM'));
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
// random tests
|
|
54
|
+
for(var i=1; i<128; i++) {
|
|
55
|
+
var rand = require('crypto').pseudoRandomBytes(i);
|
|
56
|
+
doTest('Random Short Buffer', 'crc32', rand);
|
|
57
|
+
}
|
|
58
|
+
for(var i=0; i<32; i++) {
|
|
59
|
+
var rand = require('crypto').pseudoRandomBytes(100000);
|
|
60
|
+
doTest('Random Buffer', 'crc32', rand);
|
|
61
|
+
|
|
62
|
+
var split = Math.random()*rand.length;
|
|
63
|
+
doTest('Random Continue Buffer', 'crc32', [rand.slice(split), ycrc32(rand.slice(0, split))], crc32(rand));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
53
67
|
console.log('All tests passed');
|
package/test/testdec.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// a basic script to test that raw yEnc works as expected
|
|
2
2
|
|
|
3
|
+
var allocBuffer = (Buffer.allocUnsafe || Buffer);
|
|
4
|
+
var toBuffer = (Buffer.alloc ? Buffer.from : Buffer);
|
|
5
|
+
|
|
3
6
|
var assert = require('assert');
|
|
4
7
|
var y = (function() {
|
|
5
8
|
try {
|
|
@@ -14,12 +17,12 @@ var ord = function(c) {
|
|
|
14
17
|
// slow reference yEnc implementation
|
|
15
18
|
var refYDec = function(src, findEnd) {
|
|
16
19
|
var ret = [];
|
|
17
|
-
if(findEnd && chr(src[0]) == '=' && chr(src[1]) == 'y') return
|
|
20
|
+
if(findEnd && chr(src[0]) == '=' && chr(src[1]) == 'y') return allocBuffer(0);
|
|
18
21
|
for (var i = 0; i < src.length; i++) {
|
|
19
22
|
switch(chr(src[i])) {
|
|
20
23
|
case '\r':
|
|
21
24
|
if(findEnd && chr(src[i+1]) == '\n' && chr(src[i+2]) == '=' && chr(src[i+3]) == 'y')
|
|
22
|
-
return
|
|
25
|
+
return toBuffer(ret);
|
|
23
26
|
case '\n': continue;
|
|
24
27
|
case '=':
|
|
25
28
|
i++;
|
|
@@ -30,7 +33,7 @@ var refYDec = function(src, findEnd) {
|
|
|
30
33
|
}
|
|
31
34
|
ret.push((src[i] - 42) & 0xFF);
|
|
32
35
|
}
|
|
33
|
-
return
|
|
36
|
+
return toBuffer(ret);
|
|
34
37
|
};
|
|
35
38
|
var refYDecRaw = function(src, findEnd) {
|
|
36
39
|
// undo NNTP layer
|
|
@@ -39,7 +42,7 @@ var refYDecRaw = function(src, findEnd) {
|
|
|
39
42
|
if(src[0] == ord('.')) {
|
|
40
43
|
i++;
|
|
41
44
|
if(findEnd && src[1] == ord('\r') && src[2] == ord('\n'))
|
|
42
|
-
return
|
|
45
|
+
return allocBuffer(0);
|
|
43
46
|
}
|
|
44
47
|
// TODO: do leading/trailing spaces/tabs need to be trimmed?
|
|
45
48
|
for(; i<src.length; i++) {
|
|
@@ -61,17 +64,24 @@ var refYDecRaw = function(src, findEnd) {
|
|
|
61
64
|
var testFuncs = [
|
|
62
65
|
{l: 'nntp', r: refYDecRaw, a: function(s) {
|
|
63
66
|
return y.decode(s, true);
|
|
67
|
+
}, i: function(b) {
|
|
68
|
+
return y.decodeTo(b, b, true);
|
|
69
|
+
}},
|
|
70
|
+
{l: 'plain', r: refYDec, a: y.decode, i: function(b) {
|
|
71
|
+
return y.decodeTo(b, b, false);
|
|
64
72
|
}},
|
|
65
|
-
{l: 'plain', r: refYDec, a: y.decode},
|
|
66
73
|
{l: 'nntp-end', r: function(s) {
|
|
67
74
|
return refYDecRaw(s, true);
|
|
68
75
|
}, a: function(s) {
|
|
69
76
|
if(!s.length) return Buffer(0);
|
|
70
77
|
return y.decodeIncr(s).output;
|
|
78
|
+
}, i: function(b) {
|
|
79
|
+
if(!b.length) return 0;
|
|
80
|
+
return y.decodeIncr(b, 0, b).written;
|
|
71
81
|
}}
|
|
72
82
|
];
|
|
73
83
|
var doTest = function(msg, data, expected) {
|
|
74
|
-
data =
|
|
84
|
+
data = toBuffer(data);
|
|
75
85
|
|
|
76
86
|
var prepad = 48, postpad = 48;
|
|
77
87
|
if(data.length > 1024) {
|
|
@@ -80,17 +90,17 @@ var doTest = function(msg, data, expected) {
|
|
|
80
90
|
}
|
|
81
91
|
|
|
82
92
|
for(var i=0; i<prepad; i++) {
|
|
83
|
-
var pre =
|
|
93
|
+
var pre = allocBuffer(i);
|
|
84
94
|
pre.fill(1);
|
|
85
95
|
for(var j=0; j<postpad; j++) {
|
|
86
96
|
testFuncs.forEach(function(f) {
|
|
87
|
-
var post =
|
|
97
|
+
var post = allocBuffer(j);
|
|
88
98
|
post.fill(1);
|
|
89
99
|
|
|
90
100
|
var testData = Buffer.concat([pre, data, post]);
|
|
91
101
|
var x;
|
|
92
102
|
if(expected === undefined) x = f.r(testData).toString('hex');
|
|
93
|
-
else x =
|
|
103
|
+
else x = toBuffer(expected).toString('hex').replace(/ /g, '');
|
|
94
104
|
var actual = f.a(testData).toString('hex');
|
|
95
105
|
if(actual != x) {
|
|
96
106
|
console.log('Actual:', actual);
|
|
@@ -98,6 +108,14 @@ var doTest = function(msg, data, expected) {
|
|
|
98
108
|
console.log('Source:', data.toString('hex'));
|
|
99
109
|
assert.equal(actual, x, msg + ' [' + i + '/' + j + ' ' + f.l + ']');
|
|
100
110
|
}
|
|
111
|
+
// also test in-situ decoding
|
|
112
|
+
var ilen = f.i(testData);
|
|
113
|
+
actual = testData.slice(0, ilen).toString('hex');
|
|
114
|
+
if(actual != x) {
|
|
115
|
+
console.log('Actual:', actual);
|
|
116
|
+
console.log('Expect:', x);
|
|
117
|
+
assert.equal(actual, x, msg + ' (in-situ) [' + i + '/' + j + ' ' + f.l + ']');
|
|
118
|
+
}
|
|
101
119
|
});
|
|
102
120
|
if(expected !== undefined) return; // if given expected string, only do one test
|
|
103
121
|
|
|
@@ -137,7 +155,7 @@ doTest('Bad escape, Yenc end sequence', '=\r\n=y');
|
|
|
137
155
|
|
|
138
156
|
|
|
139
157
|
// longer tests
|
|
140
|
-
var b =
|
|
158
|
+
var b = allocBuffer(256);
|
|
141
159
|
b.fill(0);
|
|
142
160
|
doTest('Long no escaping', b);
|
|
143
161
|
b.fill('='.charCodeAt(0));
|
|
@@ -155,9 +173,7 @@ b.fill(223);
|
|
|
155
173
|
doTest('Long all tabs', b);
|
|
156
174
|
|
|
157
175
|
// test for past bug in ARMv8 NEON decoder where nextMask wasn't properly compensated for
|
|
158
|
-
doTest('Extra null issue',
|
|
159
|
-
// end detection bug
|
|
160
|
-
doTest('End detect', new Buffer('612e6161610d610d612e793d3d0d0d2e612e2e0a0d0d61792e3d3d61612e0d0a2e0d2e0a0d79612e0a3d2e2e793d2e610a0d0a0a2e793d790d612e61612e0a3d792e2e3d2e7961793d792e0a61790a0d0a2e0d0a3d0a0d0d0d0a610a0a6161792e3d2e0a2e0d0d0d613d610a0a0a793d613d3d0a3d790d3d0a0a2e2e7979796179613d0d2e792e793d3d61792e612e2e2e793d616161790d0d2e0d0d793d0d790a0a3d0d617979790d2e0d792e612e610a0a0a0a0a79790d0a610d612e0d0a0d3d0a61792e2e0a790d0d792e790d0a2e79612e3d0a79790a0d0d3d0a0a0d3d0a7961610a2e613d792e0a612e613d610a2e0a0a79613d2e2e0d3d3d2e793d792e792e0d0d610d2e2e0d2e79610d2e790d790d3d2e3d790a0a0d0a0a0a612e2e79612e0d2e3d793d2e0a2e3d790a2e3d792e2e610d3d2e0d3d3d0a3d2e0d613d2e0d61610a3d0a2e0a0a3d3d612e3d790d6161613d3d612e3d0d0a2e0d0d0d616179790a2e3d610d612e0d2e3d0d0a3d610d0d61610a7961613d2e790d613d610a3d612e0a2e0d79790d0a610a2e2e0a2e612e2e0d792e61610a2e0d610d3d0a793d613d0d3d0a3d0d0a613d2e0a3d610a3d0d793d0d7979792e3d613d0a2e61610d793d2e0a0a2e612e0d2e2e792e0d2e613d0d790a0d2e610d2e0a2e61793d0d0d0a0a0d0d2e2e0d2e793d3d79612e0a610a610a0d610d0d2e2e790', 'hex'));
|
|
176
|
+
doTest('Extra null issue', toBuffer('2e900a4fb6054c9126171cdc196dc41237bb1b76da9191aa5e85c1d2a2a5c638fe39054a210e8c799473cd510541fd118f3904b242a9938558c879238aae1d3bdab32e287cedb820b494f54ffae6dd0b13f73a4a9499df486a7845c612182bcef72a6e50a8e98351c35765d26c605115dc8c5c56a5e3f20ae6da8dcd78536e6d1601eb1fc3ddc774', 'hex'));
|
|
161
177
|
|
|
162
178
|
// random tests
|
|
163
179
|
for(var i=0; i<32; i++) {
|
|
@@ -168,7 +184,7 @@ for(var i=0; i<32; i++) {
|
|
|
168
184
|
// targeted random tests
|
|
169
185
|
var charset = '=\r\n.ay';
|
|
170
186
|
var randStr = function(n) {
|
|
171
|
-
var ret =
|
|
187
|
+
var ret = allocBuffer(n);
|
|
172
188
|
for(var i=0; i<n; i++)
|
|
173
189
|
ret[i] = ord(charset[(Math.random() * charset.length) | 0]);
|
|
174
190
|
return ret;
|
package/test/testenc.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// a basic script to test that raw yEnc works as expected
|
|
2
2
|
|
|
3
3
|
var assert = require('assert');
|
|
4
|
+
var allocBuffer = (Buffer.allocUnsafe || Buffer);
|
|
5
|
+
var toBuffer = (Buffer.alloc ? Buffer.from : Buffer);
|
|
6
|
+
|
|
4
7
|
var y = (function() {
|
|
5
8
|
try {
|
|
6
9
|
return require('../build/Debug/yencode.node');
|
|
@@ -47,10 +50,10 @@ var refYEnc = function(src, line_size, col) {
|
|
|
47
50
|
ret.push((c+64) & 0xFF);
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
return
|
|
53
|
+
return toBuffer(ret);
|
|
51
54
|
};
|
|
52
55
|
var doTest = function(msg, test, expected) {
|
|
53
|
-
test[0] =
|
|
56
|
+
test[0] = toBuffer(test[0]);
|
|
54
57
|
if(!test[1]) test[1] = 128; // line size
|
|
55
58
|
if(!test[2]) test[2] = 0; // column offset
|
|
56
59
|
|
|
@@ -64,7 +67,7 @@ var doTest = function(msg, test, expected) {
|
|
|
64
67
|
assert.equal(actual, expected, msg);
|
|
65
68
|
}
|
|
66
69
|
|
|
67
|
-
var buf =
|
|
70
|
+
var buf = allocBuffer(maxSize(test[0].length, test[1]));
|
|
68
71
|
var len = y.encodeTo.apply(null, [test[0], buf].concat(test.slice(1)));
|
|
69
72
|
assert.equal(buf.slice(0, len).toString('hex'), expected, msg);
|
|
70
73
|
};
|
|
@@ -97,7 +100,7 @@ var runLineSizes = function(fn) {
|
|
|
97
100
|
// simple tests
|
|
98
101
|
runLineSizes(function(ls, offs) {
|
|
99
102
|
var infoStr = ' [ls='+ls+', offs='+offs+']';
|
|
100
|
-
var b =
|
|
103
|
+
var b = allocBuffer(256);
|
|
101
104
|
b.fill(0);
|
|
102
105
|
doTest('Long no escaping' + infoStr, [b, ls]);
|
|
103
106
|
b.fill(227);
|
|
@@ -110,7 +113,7 @@ runLineSizes(function(ls, offs) {
|
|
|
110
113
|
|
|
111
114
|
// case tests
|
|
112
115
|
var padLens = range(0, 35).concat(range(46, 51)).concat(range(62, 67));
|
|
113
|
-
var padding =
|
|
116
|
+
var padding = allocBuffer(128);
|
|
114
117
|
padding.fill(97); // 'a'
|
|
115
118
|
[ ['Empty test', [[]], ''],
|
|
116
119
|
['Simple test', [[0,1,2,3,224,4]]],
|
|
@@ -127,7 +130,7 @@ padding.fill(97); // 'a'
|
|
|
127
130
|
// if no defined result, try padding the data to make it long enough to invoke SIMD behaviour
|
|
128
131
|
padLens.forEach(function(prepad) {
|
|
129
132
|
padLens.forEach(function(postpad) {
|
|
130
|
-
var newBuf = Buffer.concat([padding.slice(0, prepad),
|
|
133
|
+
var newBuf = Buffer.concat([padding.slice(0, prepad), toBuffer(test[1][0]), padding.slice(0, postpad)]);
|
|
131
134
|
var newTest = test.slice();
|
|
132
135
|
newTest[1] = [newBuf].concat(newTest[1].slice(1));
|
|
133
136
|
doTest.apply(null, newTest);
|
|
@@ -147,7 +150,7 @@ for(var i=0; i<32; i++) {
|
|
|
147
150
|
// targeted random tests
|
|
148
151
|
var charset = 'a\xd6\xdf\xe0\xe3\xf6\x04\x13';
|
|
149
152
|
var randStr = function(n) {
|
|
150
|
-
var ret =
|
|
153
|
+
var ret = allocBuffer(n);
|
|
151
154
|
for(var i=0; i<n; i++)
|
|
152
155
|
ret[i] = charset[(Math.random() * charset.length) | 0].charCodeAt(0);
|
|
153
156
|
return ret;
|
package/test/testpostdec.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
var assert = require('assert');
|
|
3
3
|
var y = require('../index.js');
|
|
4
|
+
var toBuffer = (Buffer.alloc ? Buffer.from : Buffer);
|
|
4
5
|
|
|
5
6
|
var assertObjectHas = function(obj, required) {
|
|
6
7
|
for(var k in required) {
|
|
@@ -23,7 +24,7 @@ postData = [
|
|
|
23
24
|
'=yend size=10 part=5 pcrc32=97f4bd52',
|
|
24
25
|
''
|
|
25
26
|
].join('\r\n');
|
|
26
|
-
post = y.from_post(
|
|
27
|
+
post = y.from_post(toBuffer(postData));
|
|
27
28
|
assertObjectHas(post, {
|
|
28
29
|
yencStart: 0,
|
|
29
30
|
dataStart: postData.indexOf('...'),
|
|
@@ -59,7 +60,7 @@ postData = [
|
|
|
59
60
|
'.... data',
|
|
60
61
|
'=yend size=2 pcrc32=invalid pcrc32=invalid invalid_prop',
|
|
61
62
|
].join('\r\n');
|
|
62
|
-
post = y.from_post(
|
|
63
|
+
post = y.from_post(toBuffer(postData));
|
|
63
64
|
assertObjectHas(post, {
|
|
64
65
|
yencStart: postData.indexOf('=ybegin'),
|
|
65
66
|
dataStart: postData.indexOf('...'),
|
|
@@ -97,7 +98,7 @@ postData = [
|
|
|
97
98
|
'=yend size=0',
|
|
98
99
|
''
|
|
99
100
|
].join('\r\n');
|
|
100
|
-
post = y.from_post(
|
|
101
|
+
post = y.from_post(toBuffer(postData));
|
|
101
102
|
assertObjectHas(post, {
|
|
102
103
|
yencStart: 0,
|
|
103
104
|
dataStart: undefined,
|
|
@@ -117,9 +118,9 @@ assertObjectHas(post, {
|
|
|
117
118
|
|
|
118
119
|
|
|
119
120
|
// test parse errors
|
|
120
|
-
post = y.from_post(
|
|
121
|
+
post = y.from_post(toBuffer('invalid post'));
|
|
121
122
|
assert.equal(post.code, 'no_start_found');
|
|
122
|
-
post = y.from_post(
|
|
123
|
+
post = y.from_post(toBuffer('=ybegin abc=def'));
|
|
123
124
|
assert.equal(post.code, 'no_end_found');
|
|
124
125
|
|
|
125
126
|
|