* Decodes UTF8 byte sequences in `input` to UTF32 codepoints in `target`. * The methods assumes stream input and will store partly transmitted bytes * and decode them with the next data chunk. * Note: The method does no bound checks for target, therefore make sure * the provided data chu
(input: Uint8Array, target: Uint32Array)
| 137 | * Returns the number of written codepoints in `target`. |
| 138 | */ |
| 139 | public decode(input: Uint8Array, target: Uint32Array): number { |
| 140 | const length = input.length; |
| 141 | |
| 142 | if (!length) { |
| 143 | return 0; |
| 144 | } |
| 145 | |
| 146 | let size = 0; |
| 147 | let byte1: number; |
| 148 | let byte2: number; |
| 149 | let byte3: number; |
| 150 | let byte4: number; |
| 151 | let codepoint = 0; |
| 152 | let startPos = 0; |
| 153 | |
| 154 | // handle leftover bytes |
| 155 | if (this.interim[0]) { |
| 156 | let discardInterim = false; |
| 157 | let cp = this.interim[0]; |
| 158 | cp &= ((((cp & 0xE0) === 0xC0)) ? 0x1F : (((cp & 0xF0) === 0xE0)) ? 0x0F : 0x07); |
| 159 | let pos = 0; |
| 160 | let tmp: number; |
| 161 | while ((tmp = this.interim[++pos] & 0x3F) && pos < 4) { |
| 162 | cp <<= 6; |
| 163 | cp |= tmp; |
| 164 | } |
| 165 | // missing bytes - read ahead from input |
| 166 | const type = (((this.interim[0] & 0xE0) === 0xC0)) ? 2 : (((this.interim[0] & 0xF0) === 0xE0)) ? 3 : 4; |
| 167 | const missing = type - pos; |
| 168 | while (startPos < missing) { |
| 169 | if (startPos >= length) { |
| 170 | return 0; |
| 171 | } |
| 172 | tmp = input[startPos++]; |
| 173 | if ((tmp & 0xC0) !== 0x80) { |
| 174 | // wrong continuation, discard interim bytes completely |
| 175 | startPos--; |
| 176 | discardInterim = true; |
| 177 | break; |
| 178 | } else { |
| 179 | // need to save so we can continue short inputs in next call |
| 180 | this.interim[pos++] = tmp; |
| 181 | cp <<= 6; |
| 182 | cp |= tmp & 0x3F; |
| 183 | } |
| 184 | } |
| 185 | if (!discardInterim) { |
| 186 | // final test is type dependent |
| 187 | if (type === 2) { |
| 188 | if (cp < 0x80) { |
| 189 | // wrong starter byte |
| 190 | startPos--; |
| 191 | } else { |
| 192 | target[size++] = cp; |
| 193 | } |
| 194 | } else if (type === 3) { |
| 195 | if (cp < 0x0800 || (cp >= 0xD800 && cp <= 0xDFFF) || cp === 0xFEFF) { |
| 196 | // illegal codepoint or BOM |
no test coverage detected