Skip to content

Commit 002fb3e

Browse files
committed
perf: add fast decoder for euc-kr
1 parent 0e5b9a2 commit 002fb3e

1 file changed

Lines changed: 32 additions & 16 deletions

File tree

fallback/multi-byte.js

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,43 @@ const mappers = {
1717
const euc = getTable('euc-kr')
1818
let lead = 0
1919

20-
const pushback = []
21-
const bytes = (b) => {
22-
if (lead) {
20+
const fast = (arr, start, end, stream) => {
21+
let res = ''
22+
let i = start
23+
24+
const decodeLead = (b) => {
2325
const cp = b >= 0x41 && b <= 0xfe ? euc[(lead - 0x81) * 190 + b - 0x41] : undefined
2426
lead = 0
25-
if (cp !== undefined && cp !== REP) return cp
26-
if (b < 128) pushback.push(b)
27-
return err()
27+
if (cp !== undefined && cp !== REP) {
28+
res += String.fromCharCode(cp)
29+
} else {
30+
if (b < 128) res += String.fromCharCode(b)
31+
res += String.fromCharCode(err())
32+
}
2833
}
2934

30-
if (b < 128) return b
31-
if (b < 0x81 || b === 0xff) return err()
32-
lead = b
33-
}
35+
if (lead && i < end) decodeLead(arr[i++])
36+
while (i < end) {
37+
const b = arr[i++]
38+
if (b < 128) {
39+
res += String.fromCharCode(b)
40+
} else if (b < 0x81 || b === 0xff) {
41+
res += String.fromCharCode(err())
42+
} else {
43+
lead = b
44+
if (i < end) decodeLead(arr[i++])
45+
}
46+
}
3447

35-
const eof = () => {
36-
if (!lead) return null
37-
lead = 0
38-
return err()
48+
if (lead && !stream) {
49+
lead = 0
50+
res += String.fromCharCode(err())
51+
}
52+
53+
return res
3954
}
4055

41-
return { bytes, eof, pushback }
56+
return { fast, isAscii: () => lead === 0 }
4257
},
4358
// https://encoding.spec.whatwg.org/#euc-jp-decoder
4459
'euc-jp': (err) => {
@@ -334,12 +349,13 @@ export function multibyteDecoder(enc, loose = false) {
334349

335350
let res = ''
336351
const length = arr.length
337-
if (asciiSuperset && !mapper) {
352+
if (asciiSuperset && (!mapper || mapper.isAscii?.())) {
338353
res = decodeLatin1(arr, 0, asciiPrefix(arr))
339354
if (res.length === arr.length) return res // ascii
340355
}
341356

342357
if (!mapper) mapper = mappers[enc](onErr)
358+
if (mapper.fast) return mapper.fast(arr, res.length, arr.length, stream) // does not need mapper deletion
343359
const { bytes, eof, pushback } = mapper
344360
let i = res.length
345361

0 commit comments

Comments
 (0)