@exodus/bytes 1.7.0 → 1.9.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.
@@ -8,54 +8,75 @@ const h = (x) => new Array(x).fill(r)
8
8
 
9
9
  // Common ranges
10
10
 
11
- // prettier-ignore
12
- const k8a = [9345,2,10,4,4,4,4,8,8,8,8,68,4,4,4,4,1,1,1,-627,640,-903,1,46,28,1,-8645,8833,-8817,2,5,64,9305,1,1,-8449]
13
- // prettier-ignore
14
- const k8b = [-30,1,21,-18,1,15,-17,18,-13,...e(7),16,-15,1,1,1,-13,-4,26,-1,-20,17,5,-4,-2,3]
15
- const p1 = [8237, -8235, 8089, -7816, 7820, 8, -6, 1]
16
- const p2 = [-99, 12, 20, -12, 17, 37, -29, 2]
17
- // prettier-ignore
18
- const p3 = [1,1,65,-63,158,-156,1,1,1,40,30,42,-46,6,-66,1,83,-6,-6,-67,176,...p2,-114,121,-119,1,1,155,-49,25,16,-142,159,2,-158,38,42,-46,6,-35,1,52,-6,-6,-36,145,...p2,-83,90,-88,1,1,124,-49,25,16,-111,128,2]
19
- const i0 = e(33)
20
11
  // prettier-ignore
21
12
  const i2 = [-40,-147,1,64,-62,117,-51,-63,69,-67,79,-77,79,-77,1,64,2,51,4,-116,1,124,-122,1,129,22,-148,150,-148,1,133,-131,118,-116,1,33,-31,86,-51,-32,38,-36,48,-46,48,-46,1,33,2,51,4,-85,1,93,-91,1,98,22,-117,119,-117,1,102,374]
22
- const i4a = [-75, -63, ...e(5), 104, -34, -67, 79, -77, 75, -73, 1]
23
- const i4b = [34, -32, ...e(5), 73, -34, -36, 48, -46, 44, -42, 1]
24
- const i7 = [721, 1, 1, -719, 721, -719, 721, ...e(19), r, 2, ...e(43), r]
25
- const i8 = [...e(26), r, r, 6692, 1, r]
13
+ const i4a = [-75, -63, e(5), 104, -34, -67, 79, -77, 75, -73, 1]
14
+ const i4b = [34, -32, e(5), 73, -34, -36, 48, -46, 44, -42, 1]
15
+ const i7 = [721, 1, 1, -719, 721, -719, 721, e(19), r, 2, e(43), r]
16
+ const i8 = [e(26), r, r, 6692, 1, r]
17
+ const i9 = [79, -77, e(11), 84, 46, -127, e(16), 48, -46, e(11), 53, 46]
18
+ const iB = [3425, e(57), h(4), 5, e(28), h(4)]
19
+ const p2 = [-99, 12, 20, -12, 17, 37, -29, 2]
20
+ const p1 = [8237, -8235, 8089, -7816, 7820, 8, -6, 1]
26
21
  const w0 = [8237, -8235, 8089, -8087, 8091, 8, -6, 1, -8089, 8104]
27
22
  const w8 = [8072, 1, 3, 1, 5, -15, 1]
28
- const w1 = [...w8, -7480, 7750, -8129, 7897, -7911, -182]
29
- const w3 = [...w8, -8060, 8330, -8328, 8096, -8094]
23
+ const w1 = [w8, -7480, 7750, -8129, 7897, -7911, -182]
24
+ const w3 = [w8, -8060, 8330, -8328, 8096, -8094]
30
25
  const m0 = [8558, -8328, 8374, -66, -8539, 16, 8043, -8070]
26
+ // prettier-ignore
27
+ const p3 = [1,1,65,-63,158,-156,1,1,1,40,30,42,-46,6,-66,1,83,-6,-6,-67,176,p2,-114,121,-119,1,1,155,-49,25,16,-142,159,2,-158,38,42,-46,6,-35,1,52,-6,-6,-36,145,p2,-83,90,-88,1,1,124,-49,25,16,-111,128,2]
28
+ // prettier-ignore
29
+ const k8a = [9345,2,10,4,4,4,4,8,8,8,8,68,4,4,4,4,1,1,1,-627,640,-903,1,46,28,1,-8645,8833,-8817,2,5,64,9305,1,1,-8449]
30
+ // prettier-ignore
31
+ const k8b = [-30,1,21,-18,1,15,-17,18,-13,e(7),16,-15,1,1,1,-13,-4,26,-1,-20,17,5,-4,-2,3]
31
32
 
32
33
  // prettier-ignore
33
- export default {
34
- ibm866: [913,...e(47),8530,1,1,-145,34,61,1,-12,-1,14,-18,6,6,-1,-1,-75,4,32,-8,-16,-28,60,34,1,-5,-6,21,-3,-6,-16,28,-5,1,-4,1,-12,-1,-6,1,24,-1,-82,-12,124,-4,8,4,-16,-8512,...e(15),-78,80,-77,80,-77,80,-73,80,-942,8553,-8546,8547,-260,-8306,9468,-9472],
35
- 'iso-8859-10': [...i0,100,14,16,8,-2,14,-143,148,-43,80,6,23,-208,189,-32,-154,85,14,16,8,-2,14,-128,133,-43,80,6,23,7831,-7850,-32,...i4a,1,1,117,7,-121,1,1,1,146,-144,154,-152,...e(5),...i4b,1,1,86,7,-90,1,1,1,115,-113,123,-121,1,1,1,1,58],
36
- 'iso-8859-13': [...i0,8061,-8059,1,1,8058,-8056,1,49,-47,173,-171,1,1,1,24,-22,1,1,1,8041,-8039,...p3,7835],
37
- 'iso-8859-14': [...i0,7522,1,-7520,103,1,7423,-7523,7641,-7639,7641,-119,231,-7749,1,202,7334,1,-7423,1,7455,1,-7563,7584,43,-42,44,-35,147,-111,1,-36,-7585,...e(15),165,-163,...e(5),7572,-7570,...e(5),153,-151,...e(16),134,-132,...e(5),7541,-7539,...e(5),122],
38
- 'iso-8859-15': [...i0,1,1,1,8201,-8199,187,-185,186,-184,...e(10),202,-200,1,1,199,-197,1,1,151,1,37],
39
- 'iso-8859-16': [...i0,100,1,60,8043,-142,-7870,-185,186,-184,367,-365,206,-204,205,1,-203,1,91,54,59,7840,-8039,1,199,-113,268,-350,151,1,37,4,-188,1,1,64,-62,66,-64,...e(9),65,51,-113,1,1,124,-122,132,22,-151,1,1,1,60,258,-315,1,1,1,33,-31,35,-33,...e(9),34,51,-82,1,1,93,-91,101,22,-120,1,1,1,29,258],
40
- 'iso-8859-2': [...i0,100,468,-407,-157,153,29,-179,1,184,-2,6,21,-204,208,-2,-203,85,470,-409,-142,138,29,364,-527,169,-2,6,21,355,-351,-2,...i2],
41
- 'iso-8859-3': [...i0,134,434,-565,1,r,128,-125,1,136,46,-64,22,-135,r,206,-203,119,-117,1,1,1,112,-110,1,121,46,-64,22,-120,r,191,-188,1,1,r,2,70,-2,-65,...e(8),r,2,1,1,1,76,-74,1,69,-67,1,1,1,144,-16,-125,1,1,1,r,2,39,-2,-34,...e(8),r,2,1,1,1,45,-43,1,38,-36,1,1,1,113,-16,380],
42
- 'iso-8859-4': [...i0,100,52,30,-178,132,19,-148,1,184,-78,16,68,-185,208,-206,1,85,470,-388,-163,117,19,395,-527,169,-78,16,68,-29,52,-51,...i4a,92,-26,53,7,-22,-98,1,1,1,1,154,-152,1,1,140,2,-139,...i4b,61,-26,53,7,-22,-67,1,1,1,1,123,-121,1,1,109,2,366],
43
- 'iso-8859-5': [...i0,865,...e(11),-863,865,...e(65),7367,-7365,...e(11),-949,951,1],
44
- 'iso-8859-6': [...i0,r,r,r,4,...h(7),1384,-1375,...h(13),1390,r,r,r,4,r,2,...e(25),r,r,r,r,r,6,...e(18),...h(13)],
45
- 'iso-8859-7': [...i0,8056,1,-8054,8201,3,-8201,1,1,1,721,-719,1,1,r,8040,-8037,1,1,1,721,1,1,-719,...i7],
46
- 'iso-8859-8': [...i0,r,2,...e(7),46,-44,...e(14),62,-60,1,1,1,...h(32),8025,-6727,...i8],
47
- 'koi8-r': [...k8a,8450,...e(14),-8544,8545,...e(10),-9411,933,...k8b,-28,...k8b],
48
- 'koi8-u': [...k8a,3,8448,-8446,1,8448,1,1,1,1,-8394,-51,8448,1,1,1,-8544,3,8543,-8541,1,8543,1,1,1,1,-8410,-130,-869,933,...k8b,-28,...k8b],
49
- macintosh: [69,1,2,2,8,5,6,5,-1,2,2,-1,2,2,2,-1,2,1,2,-1,2,1,2,2,-1,2,2,-1,5,-1,2,1,7972,-8048,-14,1,4,8059,-8044,41,-49,-5,8313,-8302,-12,8632,-8602,18,8518,-8557,8627,1,-8640,16,8525,15,-2,-7759,7787,-8577,16,751,-707,18,-57,-30,11,...m0,32,3,18,125,1,7872,1,8,1,-5,1,-7970,9427,-9419,121,7884,104,-115,1,56007,1,-56033,-8042,8035,4,18,-8046,8,-9,10,-3,5,1,1,-3,7,1,63531,-63533,8,1,-2,88,405,22,-557,553,1,1,-546,549,-2,-20],
50
- 'windows-1250': [...w0,-7888,7897,-7903,10,25,-4,-233,...w8,-8060,8330,-8129,7897,-7903,10,25,-4,-218,551,17,-407,-157,96,-94,1,1,1,181,-179,1,1,1,205,-203,1,554,-409,-142,1,1,1,1,77,90,-164,130,416,-415,62,...i2],
51
- 'windows-1251': [899,1,7191,-7111,7115,8,-6,1,139,-124,-7207,7216,-7215,2,-1,4,67,7110,1,3,1,5,-15,1,-8060,8330,-7369,7137,-7136,2,-1,4,-959,878,80,-86,-868,1004,-1002,1,858,-856,859,-857,1,1,1,857,-855,1,853,80,59,-988,1,1,922,7365,-7362,-921,925,-83,80,2,-71,...e(63)],
52
- 'windows-1252': [...p1,-7515,7530,-7888,7897,-7911,-197,240,-238,1,...w1,225,-6],
53
- 'windows-1253': [...p1,-8089,8104,-8102,8111,-8109,1,1,1,1,...w3,1,1,1,1,741,1,-739,1,1,1,1,1,1,r,2,1,1,1,8039,-8037,1,1,1,721,-719,1,1,...i7],
54
- 'windows-1254': [...p1,-7515,7530,-7888,7897,-7911,-197,1,1,1,...w1,1,218,-216,...e(47),79,-77,...e(11),84,46,-127,...e(16),48,-46,...e(11),53,46],
55
- 'windows-1255': [...p1,-7515,7530,-8102,8111,-8109,1,1,1,1,...w8,-7480,7750,-8328,8096,-8094,...e(7),8199,-8197,1,1,1,1,46,-44,...e(14),62,-60,1,1,1,1,1265,...e(19),45,1,1,1,1,...h(7),-36,...i8],
56
- 'windows-1256': [8237,-6702,6556,-7816,7820,8,-6,1,-7515,7530,-6583,6592,-7911,1332,18,-16,39,6505,1,3,1,5,-15,1,-6507,6777,-6801,6569,-7911,7865,1,-6483,-1562,1388,-1386,...e(7),1557,-1555,...e(14),1378,-1376,1,1,1,1377,162,-160,...e(21),-1375,1376,1,1,1,6,1,1,1,-1379,1380,-1378,1379,1,1,1,-1377,1,1,1,1,1374,1,-1372,1,1372,1,1,1,-1370,1371,1,-1369,1370,-1368,1369,-1367,1,7954,1,-6461],
57
- 'windows-1257': [...w0,-8102,8111,-8109,28,543,-527,-40,...w3,19,556,-572,1,r,2,1,1,r,2,1,49,-47,173,-171,1,1,1,24,-22,...e(5),...p3,347],
58
- 'windows-1258': [...p1,-7515,7530,-8102,8111,-7911,-197,1,1,1,...w8,-7480,7750,-8328,8096,-7911,-182,1,218,-216,...e(34),64,-62,...e(7),565,-563,1,1,65,-63,568,-566,1,204,-202,1,1,1,1,1,1,211,340,-548,1,1,1,33,-31,...e(7),534,-532,1,1,34,-32,562,-560,1,173,-171,1,1,1,1,1,1,180,7931],
59
- 'windows-874': [8237,-8235,1,1,1,8098,-8096,...e(10),...w8,-8060,...e(8),3425,...e(57),r,r,r,r,5,...e(28),r,r,r,r],
60
- 'x-mac-cyrillic': [913,...e(31),7153,-8048,992,-1005,4,8059,-8044,848,-856,-5,8313,-7456,80,7694,-7773,80,7627,-8557,8627,1,-7695,-929,988,-137,-4,80,-77,80,-78,80,-79,80,-2,-83,-857,...m0,875,80,-79,80,-7,7102,1,8,1,-5,1,-7970,7975,-7184,80,-79,80,7351,-7445,80,-2,-31,...e(30),7262]
34
+ const maps = {
35
+ ibm866: [913,e(47),8530,1,1,-145,34,61,1,-12,-1,14,-18,6,6,-1,-1,-75,4,32,-8,-16,-28,60,34,1,-5,-6,21,-3,-6,-16,28,-5,1,-4,1,-12,-1,-6,1,24,-1,-82,-12,124,-4,8,4,-16,-8512,e(15),-78,80,-77,80,-77,80,-73,80,-942,8553,-8546,8547,-260,-8306,9468,-9472],
36
+ 'koi8-r': [k8a,8450,e(14),-8544,8545,e(10),-9411,933,k8b,-28,k8b],
37
+ 'koi8-u': [k8a,3,8448,-8446,1,8448,1,1,1,1,-8394,-51,8448,1,1,1,-8544,3,8543,-8541,1,8543,1,1,1,1,-8410,-130,-869,933,k8b,-28,k8b],
38
+ 'x-mac-cyrillic': [913,e(31),7153,-8048,992,-1005,4,8059,-8044,848,-856,-5,8313,-7456,80,7694,-7773,80,7627,-8557,8627,1,-7695,-929,988,-137,-4,80,-77,80,-78,80,-79,80,-2,-83,-857,m0,875,80,-79,80,-7,7102,1,8,1,-5,1,-7970,7975,-7184,80,-79,80,7351,-7445,80,-2,-31,e(30),7262],
39
+ macintosh: [69,1,2,2,8,5,6,5,-1,2,2,-1,2,2,2,-1,2,1,2,-1,2,1,2,2,-1,2,2,-1,5,-1,2,1,7972,-8048,-14,1,4,8059,-8044,41,-49,-5,8313,-8302,-12,8632,-8602,18,8518,-8557,8627,1,-8640,16,8525,15,-2,-7759,7787,-8577,16,751,-707,18,-57,-30,11,m0,32,3,18,125,1,7872,1,8,1,-5,1,-7970,9427,-9419,121,7884,104,-115,1,56007,1,-56033,-8042,8035,4,18,-8046,8,-9,10,-3,5,1,1,-3,7,1,63531,-63533,8,1,-2,88,405,22,-557,553,1,1,-546,549,-2,-20],
40
+ 'windows-874': [8237,-8235,1,1,1,8098,-8096,e(10),w8,-8060,e(8),iB],
61
41
  }
42
+
43
+ // windows-1250 - windows-1258
44
+ // prettier-ignore
45
+ ;[
46
+ [w0,-7888,7897,-7903,10,25,-4,-233,w8,-8060,8330,-8129,7897,-7903,10,25,-4,-218,551,17,-407,-157,96,-94,1,1,1,181,-179,1,1,1,205,-203,1,554,-409,-142,1,1,1,1,77,90,-164,130,416,-415,62,i2],
47
+ [899,1,7191,-7111,7115,8,-6,1,139,-124,-7207,7216,-7215,2,-1,4,67,7110,1,3,1,5,-15,1,-8060,8330,-7369,7137,-7136,2,-1,4,-959,878,80,-86,-868,1004,-1002,1,858,-856,859,-857,1,1,1,857,-855,1,853,80,59,-988,1,1,922,7365,-7362,-921,925,-83,80,2,-71,e(63)],
48
+ [p1,-7515,7530,-7888,7897,-7911,-197,240,-238,1,w1,225,-6],
49
+ [p1,-8089,8104,-8102,8111,-8109,1,1,1,1,w3,1,1,1,1,741,1,-739,e(6),r,2,1,1,1,8039,-8037,1,1,1,721,-719,1,1,i7],
50
+ [p1,-7515,7530,-7888,7897,-7911,-197,1,1,1,w1,1,218,-216,e(47),i9],
51
+ [p1,-7515,7530,-8102,8111,-8109,1,1,1,1,w8,-7480,7750,-8328,8096,-8094,e(7),8199,-8197,1,1,1,1,46,-44,e(14),62,-60,1,1,1,1,1265,e(19),45,1,1,1,1,h(7),-36,i8],
52
+ [8237,-6702,6556,-7816,7820,8,-6,1,-7515,7530,-6583,6592,-7911,1332,18,-16,39,6505,1,3,1,5,-15,1,-6507,6777,-6801,6569,-7911,7865,1,-6483,-1562,1388,-1386,e(7),1557,-1555,e(14),1378,-1376,1,1,1,1377,162,-160,e(21),-1375,1376,1,1,1,6,1,1,1,-1379,1380,-1378,1379,1,1,1,-1377,1,1,1,1,1374,1,-1372,1,1372,1,1,1,-1370,1371,1,-1369,1370,-1368,1369,-1367,1,7954,1,-6461],
53
+ [w0,-8102,8111,-8109,28,543,-527,-40,w3,19,556,-572,1,r,2,1,1,r,2,1,49,-47,173,-171,1,1,1,24,-22,e(5),p3,347],
54
+ [p1,-7515,7530,-8102,8111,-7911,-197,1,1,1,w8,-7480,7750,-8328,8096,-7911,-182,1,218,-216,e(34),64,-62,e(7),565,-563,1,1,65,-63,568,-566,1,204,-202,e(6),211,340,-548,1,1,1,33,-31,e(7),534,-532,1,1,34,-32,562,-560,1,173,-171,e(6),180,7931],
55
+ ].forEach((m, i) => {
56
+ maps[`windows-${i + 1250}`] = m
57
+ });
58
+
59
+ // iso-8859-1 - iso-8859-16
60
+ // prettier-ignore
61
+ ;[
62
+ [], // Actual Latin1 / Unicode subset, non-WHATWG, which maps iso-8859-1 to windows-1252
63
+ [100,468,-407,-157,153,29,-179,1,184,-2,6,21,-204,208,-2,-203,85,470,-409,-142,138,29,364,-527,169,-2,6,21,355,-351,-2,i2],
64
+ [134,434,-565,1,r,128,-125,1,136,46,-64,22,-135,r,206,-203,119,-117,1,1,1,112,-110,1,121,46,-64,22,-120,r,191,-188,1,1,r,2,70,-2,-65,e(8),r,2,1,1,1,76,-74,1,69,-67,1,1,1,144,-16,-125,1,1,1,r,2,39,-2,-34,e(8),r,2,1,1,1,45,-43,1,38,-36,1,1,1,113,-16,380],
65
+ [100,52,30,-178,132,19,-148,1,184,-78,16,68,-185,208,-206,1,85,470,-388,-163,117,19,395,-527,169,-78,16,68,-29,52,-51,i4a,92,-26,53,7,-22,-98,1,1,1,1,154,-152,1,1,140,2,-139,i4b,61,-26,53,7,-22,-67,1,1,1,1,123,-121,1,1,109,2,366],
66
+ [865,e(11),-863,865,e(65),7367,-7365,e(11),-949,951,1],
67
+ [r,r,r,4,h(7),1384,-1375,h(13),1390,r,r,r,4,r,2,e(25),h(5),6,e(18),h(13)],
68
+ [8056,1,-8054,8201,3,-8201,1,1,1,721,-719,1,1,r,8040,-8037,1,1,1,721,1,1,-719,i7],
69
+ [r,2,e(7),46,-44,e(14),62,-60,1,1,1,h(32),8025,-6727,i8],
70
+ [e(47),i9], // non-WHATWG, which maps iso-8859-9 to windows-1254
71
+ [100,14,16,8,-2,14,-143,148,-43,80,6,23,-208,189,-32,-154,85,14,16,8,-2,14,-128,133,-43,80,6,23,7831,-7850,-32,i4a,1,1,117,7,-121,1,1,1,146,-144,154,-152,e(5),i4b,1,1,86,7,-90,1,1,1,115,-113,123,-121,1,1,1,1,58],
72
+ iB, // non-WHATWG, which maps iso-8859-11 to windows-874
73
+ null, // no 12
74
+ [8061,-8059,1,1,8058,-8056,1,49,-47,173,-171,1,1,1,24,-22,1,1,1,8041,-8039,p3,7835],
75
+ [7522,1,-7520,103,1,7423,-7523,7641,-7639,7641,-119,231,-7749,1,202,7334,1,-7423,1,7455,1,-7563,7584,43,-42,44,-35,147,-111,1,-36,-7585,e(15),165,-163,e(5),7572,-7570,e(5),153,-151,e(16),134,-132,e(5),7541,-7539,e(5),122],
76
+ [1,1,1,8201,-8199,187,-185,186,-184,e(10),202,-200,1,1,199,-197,1,1,151,1,37],
77
+ [100,1,60,8043,-142,-7870,-185,186,-184,367,-365,206,-204,205,1,-203,1,91,54,59,7840,-8039,1,199,-113,268,-350,151,1,37,4,-188,1,1,64,-62,66,-64,e(9),65,51,-113,1,1,124,-122,132,22,-151,1,1,1,60,258,-315,1,1,1,33,-31,35,-33,e(9),34,51,-82,1,1,93,-91,101,22,-120,1,1,1,29,258],
78
+ ].forEach((m, i) => {
79
+ if (m) maps[`iso-8859-${i + 1}`] = [e(33), m]
80
+ })
81
+
82
+ export default maps
@@ -1,6 +1,6 @@
1
1
  import { asciiPrefix, decodeAscii, decodeLatin1 } from './latin1.js'
2
2
  import encodings from './single-byte.encodings.js'
3
- import { decode2string } from './_utils.js'
3
+ import { decode2string, nativeDecoder } from './_utils.js'
4
4
 
5
5
  export const E_STRICT = 'Input is not well-formed for this encoding'
6
6
  const xUserDefined = 'x-user-defined'
@@ -13,12 +13,13 @@ export const assertEncoding = (encoding) => {
13
13
 
14
14
  const r = 0xff_fd
15
15
 
16
- function getEncoding(encoding) {
16
+ export function getEncoding(encoding) {
17
17
  assertEncoding(encoding)
18
18
  if (encoding === xUserDefined) return Array.from({ length: 128 }, (_, i) => 0xf7_80 + i)
19
19
  if (encoding === iso8i) encoding = 'iso-8859-8'
20
20
  let prev = 127
21
- return encodings[encoding].map((x) => (x === r ? x : (prev += x))) // eslint-disable-line no-return-assign
21
+ const enc = encodings[encoding].flat().flat().flat() // max depth is 3, rechecked by tests
22
+ return enc.map((x) => (x === r ? x : (prev += x))) // eslint-disable-line no-return-assign
22
23
  }
23
24
 
24
25
  const mappers = new Map()
@@ -64,6 +65,8 @@ export function encodingMapper(encoding) {
64
65
  export function encodingDecoder(encoding) {
65
66
  const cached = decoders.get(encoding)
66
67
  if (cached) return cached
68
+ const isLatin1 = encoding === 'iso-8859-1'
69
+ if (isLatin1 && !nativeDecoder) return (arr, loose = false) => decodeLatin1(arr) // native decoder is faster for ascii below
67
70
 
68
71
  let strings
69
72
  const codes = getEncoding(encoding)
@@ -77,6 +80,7 @@ export function encodingDecoder(encoding) {
77
80
 
78
81
  const prefixLen = asciiPrefix(arr)
79
82
  if (prefixLen === arr.length) return decodeAscii(arr)
83
+ if (isLatin1) return decodeLatin1(arr) // TODO: check if decodeAscii with subarray is faster for small prefixes too
80
84
  const prefix = decodeLatin1(arr, 0, prefixLen) // TODO: check if decodeAscii with subarray is faster for small prefixes too
81
85
  const suffix = decode2string(arr, prefix.length, arr.length, strings)
82
86
  if (!loose && incomplete && suffix.includes('\uFFFD')) throw new TypeError(E_STRICT)
package/fallback/utf16.js CHANGED
@@ -12,45 +12,48 @@ const to16 = (a) => new Uint16Array(a.buffer, a.byteOffset, a.byteLength / 2) //
12
12
  export function to16input(u8, le) {
13
13
  // Assume even number of bytes
14
14
  if (le === isLE) return to16(u8.byteOffset % 2 === 0 ? u8 : Uint8Array.from(u8))
15
+ return to16(swap16(Uint8Array.from(u8)))
16
+ }
17
+
18
+ export const decode = (u16, loose = false, checked = false) => {
19
+ if (checked || isWellFormed(u16)) return decodeUCS2(u16)
20
+ if (!loose) throw new TypeError(E_STRICT)
21
+ return decodeUCS2(toWellFormed(Uint16Array.from(u16))) // cloned for replacement
22
+ }
23
+
24
+ export function encode(str, loose = false, checked = false, swapped = false) {
25
+ const arr = new Uint16Array(str.length)
26
+ if (checked) return swapped ? encodeCheckedSwapped(str, arr) : encodeChecked(str, arr)
27
+ return swapped ? encodeUncheckedSwapped(str, arr, loose) : encodeUnchecked(str, arr, loose)
28
+ }
15
29
 
16
- const res = new Uint8Array(u8.length)
30
+ /* eslint-disable @exodus/mutable/no-param-reassign-prop-only */
17
31
 
32
+ // Assumes checked length % 2 === 0, otherwise does not swap tail
33
+ function swap16(u8) {
18
34
  let i = 0
19
35
  for (const last3 = u8.length - 3; i < last3; i += 4) {
20
36
  const x0 = u8[i]
21
37
  const x1 = u8[i + 1]
22
38
  const x2 = u8[i + 2]
23
39
  const x3 = u8[i + 3]
24
- res[i] = x1
25
- res[i + 1] = x0
26
- res[i + 2] = x3
27
- res[i + 3] = x2
40
+ u8[i] = x1
41
+ u8[i + 1] = x0
42
+ u8[i + 2] = x3
43
+ u8[i + 3] = x2
28
44
  }
29
45
 
30
46
  for (const last = u8.length - 1; i < last; i += 2) {
31
47
  const x0 = u8[i]
32
48
  const x1 = u8[i + 1]
33
- res[i] = x1
34
- res[i + 1] = x0
49
+ u8[i] = x1
50
+ u8[i + 1] = x0
35
51
  }
36
52
 
37
- return to16(res)
38
- }
39
-
40
- export const decode = (u16, loose = false, checked = false) => {
41
- if (checked || isWellFormed(u16)) return decodeUCS2(u16)
42
- if (!loose) throw new TypeError(E_STRICT)
43
- return decodeUCS2(toWellFormed(Uint16Array.from(u16))) // cloned for replacement
44
- }
45
-
46
- export function encode(str, loose = false, checked = false, swapped = false) {
47
- const arr = new Uint16Array(str.length)
48
- if (checked) return swapped ? encodeCheckedSwapped(str, arr) : encodeChecked(str, arr)
49
- return swapped ? encodeUncheckedSwapped(str, arr, loose) : encodeUnchecked(str, arr, loose)
53
+ return u8
50
54
  }
51
55
 
52
56
  // Splitting paths into small functions helps (at least on SpiderMonkey)
53
- /* eslint-disable @exodus/mutable/no-param-reassign-prop-only */
54
57
 
55
58
  const encodeChecked = (str, arr) => encodeCharcodes(str, arr) // Same as encodeLatin1, but with Uint16Array
56
59
 
@@ -121,6 +124,7 @@ function encodeUncheckedSwapped(str, arr, loose = false) {
121
124
  return arr
122
125
  }
123
126
 
127
+ // Only needed on Hermes, everything else has native impl
124
128
  export function toWellFormed(u16) {
125
129
  const length = u16.length
126
130
  for (let i = 0; i < length; i++) {
@@ -143,10 +147,15 @@ export function toWellFormed(u16) {
143
147
  return u16
144
148
  }
145
149
 
150
+ // Only needed on Hermes, everything else has native impl
146
151
  export function isWellFormed(u16) {
147
152
  const length = u16.length
148
153
  let i = 0
149
154
 
155
+ const m = 0x80_00_80_00
156
+ const l = 0xd8_00
157
+ const h = 0xe0_00
158
+
150
159
  // Speedup with u32, by skipping to the first surrogate
151
160
  // Only implemented for aligned input for now, but almost all input is aligned (pooled Buffer or 0 offset)
152
161
  if (length > 32 && u16.byteOffset % 4 === 0) {
@@ -158,21 +167,31 @@ export function isWellFormed(u16) {
158
167
  const b = u32[i + 1]
159
168
  const c = u32[i + 2]
160
169
  const d = u32[i + 3]
161
- if (a & 0x80_00_80_00 || b & 0x80_00_80_00 || c & 0x80_00_80_00 || d & 0x80_00_80_00) break
170
+ if (a & m || b & m || c & m || d & m) break // bitwise OR does not make this faster on Hermes
162
171
  }
163
172
 
164
- for (; i < u32length; i++) if (u32[i] & 0x80_00_80_00) break
173
+ for (; i < u32length; i++) if (u32[i] & m) break
165
174
  i *= 2
166
175
  }
167
176
 
177
+ // An extra loop gives ~30-40% speedup e.g. on English text without surrogates but with other symbols above 0x80_00
178
+ for (const last3 = length - 3; ; i += 4) {
179
+ if (i >= last3) break
180
+ const a = u16[i]
181
+ const b = u16[i + 1]
182
+ const c = u16[i + 2]
183
+ const d = u16[i + 3]
184
+ if ((a >= l && a < h) || (b >= l && b < h) || (c >= l && c < h) || (d >= l && d < h)) break
185
+ }
186
+
168
187
  for (; i < length; i++) {
169
188
  const code = u16[i]
170
- if (code >= 0xd8_00 && code < 0xe0_00) {
189
+ if (code >= l && code < h) {
171
190
  // An unexpected trail or a lead at the very end of input
172
- if (code > 0xdb_ff || i + 1 >= length) return false
191
+ if (code >= 0xdc_00 || i + 1 >= length) return false
173
192
  i++ // consume next
174
193
  const next = u16[i] // Process valid pairs immediately
175
- if (next < 0xdc_00 || next >= 0xe0_00) return false
194
+ if (next < 0xdc_00 || next >= h) return false
176
195
  }
177
196
  }
178
197
 
package/fallback/utf8.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { encodeAsciiPrefix } from './latin1.js'
2
+
1
3
  export const E_STRICT = 'Input is not well-formed utf8'
2
4
  export const E_STRICT_UNICODE = 'Input is not well-formed Unicode'
3
5
 
@@ -152,9 +154,10 @@ export function encode(string, loose) {
152
154
  const length = string.length
153
155
  let small = true
154
156
  let bytes = new Uint8Array(length) // assume ascii
155
- let p = 0
156
157
 
157
- for (let i = 0; i < length; i++) {
158
+ let i = encodeAsciiPrefix(bytes, string)
159
+ let p = i
160
+ for (; i < length; i++) {
158
161
  let code = string.charCodeAt(i)
159
162
  if (code < 0x80) {
160
163
  bytes[p++] = code
@@ -188,7 +191,7 @@ export function encode(string, loose) {
188
191
 
189
192
  if (small) {
190
193
  // TODO: use resizable array buffers? will have to return a non-resizeable one
191
- if (p !== i) throw new Error('Unreachable') // Here, p === i (only when small is still true)
194
+ if (p !== i) /* c8 ignore next */ throw new Error('Unreachable') // Here, p === i (only when small is still true)
192
195
  const bytesNew = new Uint8Array(p + (length - i) * 3) // maximium can be 3x of the string length in charcodes
193
196
  bytesNew.set(bytes)
194
197
  bytes = bytesNew
package/hex.d.ts CHANGED
@@ -19,4 +19,3 @@ export function toHex(arr: Uint8ArrayBuffer): string;
19
19
  export function fromHex(str: string, format?: 'uint8'): Uint8ArrayBuffer;
20
20
  export function fromHex(str: string, format: 'buffer'): Buffer;
21
21
  export function fromHex(str: string, format?: OutputFormat): Uint8ArrayBuffer | Buffer;
22
-
package/hex.node.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { assertUint8 } from './assert.js'
2
2
  import { typedView } from './array.js'
3
+ import { E_STRING } from './fallback/_utils.js'
3
4
  import { E_HEX } from './fallback/hex.js'
4
5
 
5
6
  if (Buffer.TYPED_ARRAY_SUPPORT) throw new Error('Unexpected Buffer polyfill')
@@ -19,7 +20,7 @@ export function toHex(arr) {
19
20
  export const fromHex = Uint8Array.fromHex
20
21
  ? (str, format = 'uint8') => typedView(Uint8Array.fromHex(str), format)
21
22
  : (str, format = 'uint8') => {
22
- if (typeof str !== 'string') throw new TypeError('Input is not a string')
23
+ if (typeof str !== 'string') throw new TypeError(E_STRING)
23
24
  if (str.length % 2 !== 0) throw new SyntaxError(E_HEX)
24
25
  if (denoBug && /[^\dA-Fa-f]/.test(str)) throw new SyntaxError(E_HEX)
25
26
  const buf = Buffer.from(str, 'hex') // will stop on first non-hex character, so we can just validate length
package/index.d.ts ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * ### The `@exodus/bytes` package consists of submodules, there is no single export.
3
+ * Import specific submodules instead.
4
+ *
5
+ * See [README](https://github.com/ExodusOSS/bytes/blob/main/README.md).
6
+ *
7
+ * Example:
8
+ * ```js
9
+ * import { fromHex, toHex } from '@exodus/bytes/hex.js'
10
+ * import { fromBase64, toBase64, fromBase64url, toBase64url, fromBase64any } from '@exodus/bytes/base64.js'
11
+ * import { fromBase32, toBase32, fromBase32hex, toBase32hex } from '@exodus/bytes/base32.js'
12
+ * import { fromBase58, toBase58, fromBase58xrp, toBase58xrp } from '@exodus/bytes/base58.js'
13
+ * import { fromBech32, toBech32, fromBech32m, toBech32m, getPrefix } from '@exodus/bytes/bech32.js'
14
+ * import { fromBigInt, toBigInt } from '@exodus/bytes/bigint.js'
15
+ *
16
+ * import { utf8fromString, utf8toString, utf8fromStringLoose, utf8toStringLoose } from '@exodus/bytes/utf8.js'
17
+ * import { utf16fromString, utf16toString, utf16fromStringLoose, utf16toStringLoose } from '@exodus/bytes/utf16.js'
18
+ * import {
19
+ * createSinglebyteDecoder, createSinglebyteEncoder,
20
+ * windows1252toString, windows1252fromString,
21
+ * latin1toString, latin1fromString } from '@exodus/bytes/single-byte.js'
22
+ * import { createMultibyteDecoder, createMultibyteEncoder } from '@exodus/bytes/multi-byte.js'
23
+ *
24
+ * import {
25
+ * fromBase58check, toBase58check,
26
+ * fromBase58checkSync, toBase58checkSync,
27
+ * makeBase58check } from '@exodus/bytes/base58check.js'
28
+ * import { fromWifString, toWifString, fromWifStringSync, toWifStringSync } from '@exodus/bytes/wif.js'
29
+ *
30
+ * // All encodings from the WHATWG Encoding spec
31
+ * import { TextDecoder, TextEncoder, TextDecoderStream, TextEncoderStream } from '@exodus/bytes/encoding.js'
32
+ * import { getBOMEncoding, legacyHookDecode, labelToName, normalizeEncoding } from '@exodus/bytes/encoding.js'
33
+ *
34
+ * // Omits legacy multi-byte decoders to save bundle size
35
+ * import { TextDecoder, TextEncoder, TextDecoderStream, TextEncoderStream } from '@exodus/bytes/encoding-lite.js'
36
+ * import { getBOMEncoding, legacyHookDecode, labelToName, normalizeEncoding } from '@exodus/bytes/encoding-lite.js'
37
+ *
38
+ * // In browser bundles, uses built-in TextDecoder / TextEncoder to save bundle size
39
+ * import { TextDecoder, TextEncoder, TextDecoderStream, TextEncoderStream } from '@exodus/bytes/encoding-browser.js'
40
+ * import { getBOMEncoding, legacyHookDecode, labelToName, normalizeEncoding } from '@exodus/bytes/encoding-browser.js'
41
+ * ```
42
+ */
43
+ declare module "@exodus/bytes" {}
package/index.js ADDED
@@ -0,0 +1,5 @@
1
+ throw new Error(
2
+ `This package consists of submodules, there is no single export. Import specific submodules instead.
3
+ See README: https://github.com/ExodusOSS/bytes/blob/main/README.md
4
+ `
5
+ )
package/multi-byte.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { assertUint8 } from './assert.js'
2
- import { multibyteDecoder } from './fallback/multi-byte.js'
2
+ import { multibyteDecoder, multibyteEncoder } from './fallback/multi-byte.js'
3
3
 
4
4
  export function createMultibyteDecoder(encoding, loose = false) {
5
5
  const jsDecoder = multibyteDecoder(encoding, loose) // asserts
@@ -11,3 +11,9 @@ export function createMultibyteDecoder(encoding, loose = false) {
11
11
  return jsDecoder(arr, stream)
12
12
  }
13
13
  }
14
+
15
+ export function createMultibyteEncoder(encoding, { mode = 'fatal' } = {}) {
16
+ // TODO: replacement, truncate (replacement will need varying length)
17
+ if (mode !== 'fatal') throw new Error('Unsupported mode')
18
+ return multibyteEncoder(encoding) // asserts
19
+ }
@@ -1,6 +1,6 @@
1
1
  import { assertUint8 } from './assert.js'
2
2
  import { isDeno, toBuf } from './fallback/_utils.js'
3
- import { isAsciiSuperset, multibyteDecoder } from './fallback/multi-byte.js'
3
+ import { isAsciiSuperset, multibyteDecoder, multibyteEncoder } from './fallback/multi-byte.js'
4
4
  import { isAscii } from 'node:buffer'
5
5
 
6
6
  export function createMultibyteDecoder(encoding, loose = false) {
@@ -21,3 +21,9 @@ export function createMultibyteDecoder(encoding, loose = false) {
21
21
  return jsDecoder(arr, stream)
22
22
  }
23
23
  }
24
+
25
+ export function createMultibyteEncoder(encoding, { mode = 'fatal' } = {}) {
26
+ // TODO: replacement, truncate (replacement will need varying length)
27
+ if (mode !== 'fatal') throw new Error('Unsupported mode')
28
+ return multibyteEncoder(encoding) // asserts
29
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/bytes",
3
- "version": "1.7.0",
3
+ "version": "1.9.0",
4
4
  "description": "Various operations on Uint8Array data",
5
5
  "scripts": {
6
6
  "lint": "eslint .",
@@ -23,6 +23,7 @@
23
23
  "test:firefox:playwright": "exodus-test --engine=firefox:playwright",
24
24
  "test:servo:bundle": "exodus-test --engine=servo:bundle",
25
25
  "test": "exodus-test",
26
+ "size": "esbuild --minify --bundle",
26
27
  "jsvu": "jsvu",
27
28
  "playwright": "exodus-test --playwright",
28
29
  "benchmark": "exodus-test --concurrency=1 benchmarks/*.bench.js",
@@ -48,6 +49,7 @@
48
49
  "/fallback/base58check.js",
49
50
  "/fallback/base64.js",
50
51
  "/fallback/encoding.js",
52
+ "/fallback/encoding.api.js",
51
53
  "/fallback/encoding.labels.js",
52
54
  "/fallback/encoding.util.js",
53
55
  "/fallback/hex.js",
@@ -71,11 +73,19 @@
71
73
  "/base64.d.ts",
72
74
  "/bech32.js",
73
75
  "/bigint.js",
76
+ "/encoding-browser.js",
77
+ "/encoding-browser.browser.js",
78
+ "/encoding-browser.native.js",
79
+ "/encoding-browser.d.ts",
74
80
  "/encoding.js",
81
+ "/encoding.d.ts",
75
82
  "/encoding-lite.js",
83
+ "/encoding-lite.d.ts",
76
84
  "/hex.js",
77
85
  "/hex.d.ts",
78
86
  "/hex.node.js",
87
+ "/index.js",
88
+ "/index.d.ts",
79
89
  "/multi-byte.js",
80
90
  "/multi-byte.node.js",
81
91
  "/single-byte.js",
@@ -87,7 +97,14 @@
87
97
  "/utf8.node.js",
88
98
  "/wif.js"
89
99
  ],
100
+ "main": "index.js",
101
+ "module": "index.js",
102
+ "types": "index.d.ts",
90
103
  "exports": {
104
+ ".": {
105
+ "types": "./index.d.ts",
106
+ "default": "./index.js"
107
+ },
91
108
  "./array.js": {
92
109
  "types": "./array.d.ts",
93
110
  "default": "./array.js"
@@ -117,8 +134,21 @@
117
134
  "node": "./single-byte.node.js",
118
135
  "default": "./single-byte.js"
119
136
  },
120
- "./encoding.js": "./encoding.js",
121
- "./encoding-lite.js": "./encoding-lite.js",
137
+ "./encoding.js": {
138
+ "types": "./encoding.d.ts",
139
+ "default": "./encoding.js"
140
+ },
141
+ "./encoding-lite.js": {
142
+ "types": "./encoding-lite.d.ts",
143
+ "default": "./encoding-lite.js"
144
+ },
145
+ "./encoding-browser.js": {
146
+ "types": "./encoding-browser.d.ts",
147
+ "node": "./encoding-browser.js",
148
+ "react-native": "./encoding-browser.native.js",
149
+ "browser": "./encoding-browser.browser.js",
150
+ "default": "./encoding-browser.js"
151
+ },
122
152
  "./utf16.js": {
123
153
  "node": "./utf16.node.js",
124
154
  "default": "./utf16.js"
@@ -130,11 +160,14 @@
130
160
  },
131
161
  "./wif.js": "./wif.js"
132
162
  },
163
+ "react-native": {
164
+ "./encoding-browser.js": "./encoding-browser.native.js"
165
+ },
133
166
  "peerDependencies": {
134
- "@exodus/crypto": "^1.0.0-rc.4"
167
+ "@noble/hashes": "^1.8.0 || ^2.0.0"
135
168
  },
136
169
  "peerDependenciesMeta": {
137
- "@exodus/crypto": {
170
+ "@noble/hashes": {
138
171
  "optional": true
139
172
  }
140
173
  },
@@ -145,6 +178,7 @@
145
178
  "@exodus/prettier": "^1.0.0",
146
179
  "@exodus/test": "^1.0.0-rc.109",
147
180
  "@noble/hashes": "^2.0.1",
181
+ "@oslojs/encoding": "^1.1.0",
148
182
  "@petamoriken/float16": "^3.9.3",
149
183
  "@scure/base": "^1.2.6",
150
184
  "@stablelib/base64": "^2.0.1",
@@ -159,9 +193,11 @@
159
193
  "bs58check": "^4.0.0",
160
194
  "bstring": "^0.3.9",
161
195
  "buffer": "^6.0.3",
196
+ "c8": "^10.1.3",
162
197
  "decode-utf8": "^1.0.1",
163
198
  "electron": "36.5.0",
164
199
  "encode-utf8": "^2.0.0",
200
+ "esbuild": "^0.27.2",
165
201
  "eslint": "^8.44.0",
166
202
  "fast-base64-decode": "^2.0.0",
167
203
  "fast-base64-encode": "^1.0.0",
@@ -169,12 +205,12 @@
169
205
  "hi-base32": "^0.5.1",
170
206
  "iconv-lite": "^0.7.0",
171
207
  "jsvu": "^3.0.3",
208
+ "punycode": "^2.3.1",
172
209
  "text-encoding": "^0.7.0",
173
210
  "typescript": "^5.9.3",
174
211
  "uint8array-tools": "^0.0.9",
175
212
  "utf8": "^3.0.0",
176
213
  "web-streams-polyfill": "^4.2.0",
177
- "whatwg-encoding": "^3.1.1",
178
214
  "wif": "^5.0.0"
179
215
  },
180
216
  "prettier": "@exodus/prettier",