Skip to content

Commit 23fed09

Browse files
committed
perf: add fast decoder for euc-jp
1 parent f680ad2 commit 23fed09

File tree

1 file changed

+36
-23
lines changed

1 file changed

+36
-23
lines changed

fallback/multi-byte.js

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -58,45 +58,58 @@ const mappers = {
5858
let j12 = false
5959
let lead = 0
6060

61-
const pushback = []
62-
const bytes = (b) => {
61+
const decodeLead = (b) => {
6362
if (lead === 0x8e && b >= 0xa1 && b <= 0xdf) {
6463
lead = 0
65-
return 0xfe_c0 + b
64+
return String.fromCharCode(0xfe_c0 + b)
6665
}
6766

6867
if (lead === 0x8f && b >= 0xa1 && b <= 0xfe) {
6968
j12 = true
7069
lead = b
71-
return
70+
return ''
7271
}
7372

74-
if (lead) {
75-
let cp
76-
if (lead >= 0xa1 && lead <= 0xfe && b >= 0xa1 && b <= 0xfe) {
77-
cp = (j12 ? jis0212 : jis0208)[(lead - 0xa1) * 94 + b - 0xa1]
73+
let cp
74+
if (lead >= 0xa1 && lead <= 0xfe && b >= 0xa1 && b <= 0xfe) {
75+
cp = (j12 ? jis0212 : jis0208)[(lead - 0xa1) * 94 + b - 0xa1]
76+
}
77+
78+
lead = 0
79+
j12 = false
80+
if (cp !== undefined && cp !== REP) return String.fromCharCode(cp)
81+
return b < 128 ? String.fromCharCode(err(), b) : String.fromCharCode(err())
82+
}
83+
84+
const fast = (arr, start, end, stream) => {
85+
let res = ''
86+
let i = start
87+
88+
if (lead && i < end) res += decodeLead(arr[i++])
89+
while (i < end) {
90+
const b = arr[i++]
91+
if (lead) {
92+
res += decodeLead(b)
93+
} else if (b < 128) {
94+
res += String.fromCharCode(b)
95+
} else if ((b < 0xa1 && b !== 0x8e && b !== 0x8f) || b === 0xff) {
96+
res += String.fromCharCode(err())
97+
} else {
98+
lead = b
99+
if (i < end) res += decodeLead(arr[i++])
78100
}
101+
}
79102

103+
if (lead && !stream) {
80104
lead = 0
81-
j12 = false
82-
if (cp !== undefined && cp !== REP) return cp
83-
if (b < 128) pushback.push(b)
84-
return err()
105+
j12 = false // can be true only when lead is non-zero
106+
res += String.fromCharCode(err())
85107
}
86108

87-
if (b < 128) return b
88-
if ((b < 0xa1 && b !== 0x8e && b !== 0x8f) || b === 0xff) return err()
89-
lead = b
90-
}
91-
92-
// eslint-disable-next-line sonarjs/no-identical-functions
93-
const eof = () => {
94-
if (!lead) return null
95-
lead = 0
96-
return err()
109+
return res
97110
}
98111

99-
return { bytes, eof, pushback }
112+
return { fast, isAscii: () => lead === 0 } // j12 can be true only when lead is non-zero
100113
},
101114
// https://encoding.spec.whatwg.org/#iso-2022-jp-decoder
102115
// Per-letter of the spec, don't shortcut on state changes on EOF. Some code is regrouped but preserving the logic

0 commit comments

Comments
 (0)