ag-psd 15.0.3 → 15.0.5

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/utf8.ts ADDED
@@ -0,0 +1,160 @@
1
+ function charLengthInBytes(code: number): number {
2
+ if ((code & 0xffffff80) === 0) {
3
+ return 1;
4
+ } else if ((code & 0xfffff800) === 0) {
5
+ return 2;
6
+ } else if ((code & 0xffff0000) === 0) {
7
+ return 3;
8
+ } else {
9
+ return 4;
10
+ }
11
+ }
12
+
13
+ export function stringLengthInBytes(value: string): number {
14
+ let result = 0;
15
+
16
+ for (let i = 0; i < value.length; i++) {
17
+ const code = value.charCodeAt(i);
18
+
19
+ // high surrogate
20
+ if (code >= 0xd800 && code <= 0xdbff) {
21
+ if ((i + 1) < value.length) {
22
+ const extra = value.charCodeAt(i + 1);
23
+
24
+ // low surrogate
25
+ if ((extra & 0xfc00) === 0xdc00) {
26
+ i++;
27
+ result += charLengthInBytes(((code & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000);
28
+ }
29
+ }
30
+ } else {
31
+ result += charLengthInBytes(code);
32
+ }
33
+ }
34
+
35
+ return result;
36
+ }
37
+
38
+ function writeCharacter(buffer: Uint8Array | Buffer, offset: number, code: number): number {
39
+ const length = charLengthInBytes(code);
40
+
41
+ switch (length) {
42
+ case 1:
43
+ buffer[offset] = code;
44
+ break;
45
+ case 2:
46
+ buffer[offset] = ((code >> 6) & 0x1f) | 0xc0;
47
+ buffer[offset + 1] = (code & 0x3f) | 0x80;
48
+ break;
49
+ case 3:
50
+ buffer[offset] = ((code >> 12) & 0x0f) | 0xe0;
51
+ buffer[offset + 1] = ((code >> 6) & 0x3f) | 0x80;
52
+ buffer[offset + 2] = (code & 0x3f) | 0x80;
53
+ break;
54
+ default:
55
+ buffer[offset] = ((code >> 18) & 0x07) | 0xf0;
56
+ buffer[offset + 1] = ((code >> 12) & 0x3f) | 0x80;
57
+ buffer[offset + 2] = ((code >> 6) & 0x3f) | 0x80;
58
+ buffer[offset + 3] = (code & 0x3f) | 0x80;
59
+ break;
60
+ }
61
+
62
+ return length;
63
+ }
64
+
65
+ export function encodeStringTo(buffer: Uint8Array | Buffer, offset: number, value: string): number {
66
+ for (let i = 0; i < value.length; i++) {
67
+ const code = value.charCodeAt(i);
68
+
69
+ // high surrogate
70
+ if (code >= 0xd800 && code <= 0xdbff) {
71
+ if ((i + 1) < value.length) {
72
+ const extra = value.charCodeAt(i + 1);
73
+
74
+ // low surrogate
75
+ if ((extra & 0xfc00) === 0xdc00) {
76
+ i++;
77
+ const fullCode = ((code & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
78
+ offset += writeCharacter(buffer, offset, fullCode);
79
+ }
80
+ }
81
+ } else {
82
+ offset += writeCharacter(buffer, offset, code);
83
+ }
84
+ }
85
+
86
+ return offset;
87
+ }
88
+
89
+ export function encodeString(value: string): Uint8Array {
90
+ const buffer = new Uint8Array(stringLengthInBytes(value));
91
+ encodeStringTo(buffer, 0, value);
92
+ return buffer;
93
+ }
94
+
95
+ function continuationByte(buffer: Uint8Array, index: number): number {
96
+ if (index >= buffer.length) {
97
+ throw Error('Invalid byte index');
98
+ }
99
+
100
+ const continuationByte = buffer[index];
101
+
102
+ if ((continuationByte & 0xC0) === 0x80) {
103
+ return continuationByte & 0x3F;
104
+ } else {
105
+ throw Error('Invalid continuation byte');
106
+ }
107
+ }
108
+
109
+ export function decodeString(value: Uint8Array): string {
110
+ let result = '';
111
+
112
+ for (let i = 0; i < value.length;) {
113
+ const byte1 = value[i++];
114
+ let code: number;
115
+
116
+ if ((byte1 & 0x80) === 0) {
117
+ code = byte1;
118
+ } else if ((byte1 & 0xe0) === 0xc0) {
119
+ const byte2 = continuationByte(value, i++);
120
+ code = ((byte1 & 0x1f) << 6) | byte2;
121
+
122
+ if (code < 0x80) {
123
+ throw Error('Invalid continuation byte');
124
+ }
125
+ } else if ((byte1 & 0xf0) === 0xe0) {
126
+ const byte2 = continuationByte(value, i++);
127
+ const byte3 = continuationByte(value, i++);
128
+ code = ((byte1 & 0x0f) << 12) | (byte2 << 6) | byte3;
129
+
130
+ if (code < 0x0800) {
131
+ throw Error('Invalid continuation byte');
132
+ }
133
+
134
+ if (code >= 0xd800 && code <= 0xdfff) {
135
+ throw Error(`Lone surrogate U+${code.toString(16).toUpperCase()} is not a scalar value`);
136
+ }
137
+ } else if ((byte1 & 0xf8) === 0xf0) {
138
+ const byte2 = continuationByte(value, i++);
139
+ const byte3 = continuationByte(value, i++);
140
+ const byte4 = continuationByte(value, i++);
141
+ code = ((byte1 & 0x0f) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
142
+
143
+ if (code < 0x010000 || code > 0x10ffff) {
144
+ throw Error('Invalid continuation byte');
145
+ }
146
+ } else {
147
+ throw Error('Invalid UTF-8 detected');
148
+ }
149
+
150
+ if (code > 0xffff) {
151
+ code -= 0x10000;
152
+ result += String.fromCharCode(code >>> 10 & 0x3ff | 0xd800);
153
+ code = 0xdc00 | code & 0x3ff;
154
+ }
155
+
156
+ result += String.fromCharCode(code);
157
+ }
158
+
159
+ return result;
160
+ }