| 104 | ]; |
| 105 | |
| 106 | export default class TextEncodingHandler implements FormatHandler { |
| 107 | name = "TextEncoding"; |
| 108 | supportedFormats = formats; |
| 109 | ready = true; |
| 110 | init = async () => { this.ready = true }; |
| 111 | |
| 112 | async doConvert(inputFiles: FileData[], inputFormat: FileFormat, outputFormat: FileFormat) { |
| 113 | const results: FileData[] = []; |
| 114 | for (const file of inputFiles) { |
| 115 | const inBytes = file.bytes; |
| 116 | let text = ""; |
| 117 | |
| 118 | // Determine input encoding: prefer inputFormat.internal when present |
| 119 | const inf = inputFormat.internal; |
| 120 | if (inf === "txt" || inf === "utf8NB") { |
| 121 | text = decodeUsingTextDecoder(inBytes, "utf-8"); |
| 122 | } else if (inf === "utf8WB") { |
| 123 | text = decodeUsingTextDecoder(inBytes.subarray(3), "utf-8"); |
| 124 | } else if (inf === "utf16le") { |
| 125 | text = decodeUTF16(inBytes, true); |
| 126 | } else if (inf === "utf16be") { |
| 127 | text = decodeUTF16(inBytes, false); |
| 128 | } else if (inf === "utf32le") { |
| 129 | text = decodeUTF32(inBytes, true); |
| 130 | } else if (inf === "utf32be") { |
| 131 | text = decodeUTF32(inBytes, false); |
| 132 | } else { |
| 133 | // Try BOM detection |
| 134 | if (hasPrefix(inBytes, [0xEF, 0xBB, 0xBF])) { |
| 135 | text = decodeUsingTextDecoder(inBytes.subarray(3), "utf-8"); |
| 136 | } else if (hasPrefix(inBytes, [0xFF, 0xFE, 0x00, 0x00])) { |
| 137 | text = decodeUTF32(inBytes.subarray(4), true); |
| 138 | } else if (hasPrefix(inBytes, [0x00, 0x00, 0xFE, 0xFF])) { |
| 139 | text = decodeUTF32(inBytes.subarray(4), false); |
| 140 | } else if (hasPrefix(inBytes, [0xFF, 0xFE])) { |
| 141 | text = decodeUTF16(inBytes.subarray(2), true); |
| 142 | } else if (hasPrefix(inBytes, [0xFE, 0xFF])) { |
| 143 | text = decodeUTF16(inBytes.subarray(2), false); |
| 144 | } else { |
| 145 | // default to utf-8 |
| 146 | text = decodeUsingTextDecoder(inBytes, "utf-8"); |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | // Now encode to output format |
| 151 | const outf = (outputFormat && outputFormat.internal) || "utf8NB"; |
| 152 | let outBytes: Uint8Array; |
| 153 | if (outf === "utf8NB") { |
| 154 | const utf8Bytes = new TextEncoder().encode(text); |
| 155 | if (utf8Bytes.length >= 3 && hasPrefix(utf8Bytes, [0xEF, 0xBB, 0xBF])) { |
| 156 | // has BOM, remove it |
| 157 | outBytes = utf8Bytes.subarray(3); |
| 158 | } else { |
| 159 | // Already without BOM, just use it as is |
| 160 | outBytes = utf8Bytes; |
| 161 | } |
| 162 | } else if (outf === "utf8WB") { |
| 163 | const utf8Bytes = new TextEncoder().encode(text); |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…