From 69468289917580c4a0de899cacbcaee0437fed76 Mon Sep 17 00:00:00 2001 From: Timendus Date: Fri, 19 Nov 2021 00:08:41 +0100 Subject: [PATCH 1/5] Port character encoding/decoding magic over from tilibs --- src/character-encoding/convert.js | 38 +++++++++ src/character-encoding/normalize.js | 7 ++ src/character-encoding/ti73.js | 52 ++++++++++++ src/character-encoding/ti80.js | 52 ++++++++++++ src/character-encoding/ti82.js | 52 ++++++++++++ src/character-encoding/ti83.js | 52 ++++++++++++ src/character-encoding/ti85.js | 52 ++++++++++++ src/character-encoding/ti86.js | 52 ++++++++++++ src/character-encoding/ti8x+.js | 53 ++++++++++++ src/character-encoding/ti9x.js | 107 ++++++++++++++++++++++++ test/character-encoding/convert.test.js | 24 ++++++ 11 files changed, 541 insertions(+) create mode 100644 src/character-encoding/convert.js create mode 100644 src/character-encoding/normalize.js create mode 100644 src/character-encoding/ti73.js create mode 100644 src/character-encoding/ti80.js create mode 100644 src/character-encoding/ti82.js create mode 100644 src/character-encoding/ti83.js create mode 100644 src/character-encoding/ti85.js create mode 100644 src/character-encoding/ti86.js create mode 100644 src/character-encoding/ti8x+.js create mode 100644 src/character-encoding/ti9x.js create mode 100644 test/character-encoding/convert.test.js diff --git a/src/character-encoding/convert.js b/src/character-encoding/convert.js new file mode 100644 index 0000000..a5f99e1 --- /dev/null +++ b/src/character-encoding/convert.js @@ -0,0 +1,38 @@ +const charEncodings = { + 'TI-73': require('./ti73'), + 'TI-82': require('./ti82'), + 'TI-83': require('./ti83'), + 'TI-84 Plus': require('./ti8x+'), + 'TI-85': require('./ti85'), + 'TI-86': require('./ti86'), + 'TI-89': require('./ti9x'), + 'TI-92': require('./ti9x'), + 'TI-92 Plus': require('./ti9x'), + 'TI-V200': require('./ti9x'), + //'TI-CBL2': require(???), +} + +module.exports = { + // String in, string out + toUTF16: (charset, input) => + convert(charset, input, (cs, c) => cs[c]), + fromUTF16: (charset, input) => + convert(charset, input, (cs, c) => cs.indexOf(c)), + + // Uint8Array in, string out + parse: (input, calcType) => { + let charset = charEncodings[calcType]; + if (!charset) return "Decoding error: can't decode strings for this calculator type"; + let output = ''; + for ( c of input ) { + output += String.fromCharCode(charset[c]); + } + return output; + } +}; + +function convert(charset, input, lookup) { + return input.split('') + .map(c => String.fromCharCode(lookup(charset, c.charCodeAt(0)))) + .join(''); +} diff --git a/src/character-encoding/normalize.js b/src/character-encoding/normalize.js new file mode 100644 index 0000000..42bcd01 --- /dev/null +++ b/src/character-encoding/normalize.js @@ -0,0 +1,7 @@ +// The character sets from tilibs contain hexadecimal numbers and characters. +// In C this is all just binary numbers, but JavaScript interprets the +// characters as strings and messes things up. This normalizes it all back down +// to numeric values. + +module.exports = charset => + charset.map(c => typeof c == 'string' ? c.charCodeAt(0) : c); diff --git a/src/character-encoding/ti73.js b/src/character-encoding/ti73.js new file mode 100644 index 0000000..300ada0 --- /dev/null +++ b/src/character-encoding/ti73.js @@ -0,0 +1,52 @@ +// Conversion table for going from TI characters to UTF16 +// Adapted from https://github.com/debrouxl/tilibs/blob/experimental2/libticonv/trunk/src/charset.cc + +module.exports = require('./normalize')([ + '\0', 0x3b7, 'u', 'v', 'w', 0x25b6, 0x2191, 0x2193, // [0x01-0x05] != TI83 + 0x222b, 'x', 176, 184, 183, 0x22ba, 179, 'F', + + 0x221a, 180, 178, 0x2220, 176, 0x2b3, 0x22ba, 0x2264, + 0x2260, 0x2265, 0x2212, 0xd875dda4,0x2192,'?', 0x2191, 0x2193, + + ' ', '!', '\"', '#', 0x2074, '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x3b8, '\\', ']', '^', '_', + + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', '=', + + 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087, + 0x2088, 0x2089, 192+1, 192+0, 192+2, 192+4, 224+1, 224+0, + + 224+2, 224+4, 200+1, 200+0, 200+2, 200+4, 231+1, 231+0, + 231+2, 231+4, 204+1, 204+0, 204+2, 204+3, 236+1, 236+0, + + 236+2, 236+3, 210+1, 210+0, 210+2, 210+4, 242+1, 242+0, + 242+2, 242+4, 217+1, 217+0, 217+2, 217+3, 249+1, 249+0, + + 249+2, 249+3, 199, 231, 209, 204, '\'', '`', + 0x0a8, 0x0bf, 0x0a1, 0x3b1, 0x3b2, 0x3b3, 0x394, 0x3b4, + + 0x3b5, '[', 0x3bb, 0x3bc, 0x3c0, 0x3c1, 0x3a3, 0x3c3, + 0x3c4, 0x3d5, 0x3a9, 'x', 'y', '?', 0x2026, 0x25c0, + + 0x25fe, '?', 0x2212, 178, 176, 179, '\n', '_', + '_', 169, 'L', 0x212f, 'L', 'N', '_' /*))*/,0x2192, + + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', +]); diff --git a/src/character-encoding/ti80.js b/src/character-encoding/ti80.js new file mode 100644 index 0000000..2b79769 --- /dev/null +++ b/src/character-encoding/ti80.js @@ -0,0 +1,52 @@ +// Conversion table for going from TI characters to UTF16 +// Adapted from https://github.com/debrouxl/tilibs/blob/experimental2/libticonv/trunk/src/charset.cc + +module.exports = require('./normalize')([ + ' ', 0x2588, '_', 0x2191, 'A', 0x25b6, '%', '(', // 0x00-0x7F + ')', '\"', ',', '!', 176, '\'', 0x2b3, 180, + + 178, 'a', 'b', 'c', 'd', 'e', 'n', 'r', + 0x2423, 'x', 'y', 0x2081, 0x2080, 0x3c0, 0xffff, '=', + + 'X', 'Y', 'T', 'R', 0x3b8, 0x2025, 0x25a1, 0x207a, + 0x2d9, '{', '}', 179, '.', 0x1d07, 0x2044, ':', + + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '=', 0x2260, '>', 0x2265, '<', 0x2264, + + '?', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x3b8, '+', '-', 0x00d7, '/', + + '^', 0x207b, 0x221a, 0x3a3, 0x3c3, 0x1e8b, 0x1e8f, 0x394, + 0x1d1b, 0x2191, 0x2193, 0x2e3, 247, '_', '_', '_', + + '_', '_', '_', '_', '_', 0x2592, 0x2af0, 179, + '_', '_', '_', '_', '_', '_', '_', '_', + + ' ', 0x2588, '_', 0x2191, 'A', 0x25b6, '%', '(', // 0x80-0xFF onwards: same as 0x00-0x7F + ')', '\"', ',', '!', 176, '\'', 0x2b3, 180, + + 178, 'a', 'b', 'c', 'd', 'e', 'n', 'r', + 0x2423, 'x', 'y', 0x2081, 0x2080, 0x3c0, 0xffff, '=', + + 'X', 'Y', 'T', 'R', 0x3b8, 0x2025, 0x25a1, 0x207a, + 0x2d9, '{', '}', 179, '.', 0x1d07, 0x2044, ':', + + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '=', 0x2260, '>', 0x2265, '<', 0x2264, + + '?', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x3b8, '+', '-', 0x00d7, '/', + + '^', 0x207b, 0x221a, 0x3a3, 0x3c3, 0x1e8b, 0x1e8f, 0x394, + 0x1d1b, 0x2191, 0x2193, 0x2e3, 247, '_', '_', '_', + + '_', '_', '_', '_', '_', 0x2592, 0x2af0, 179, + '_', '_', '_', '_', '_', '_', '_', '_', +]); diff --git a/src/character-encoding/ti82.js b/src/character-encoding/ti82.js new file mode 100644 index 0000000..b1c1883 --- /dev/null +++ b/src/character-encoding/ti82.js @@ -0,0 +1,52 @@ +// Conversion table for going from TI characters to UTF16 +// Adapted from https://github.com/debrouxl/tilibs/blob/experimental2/libticonv/trunk/src/charset.cc + +module.exports = require('./normalize')([ + '\0', 'b', 'o', 'd', 'h', 0x25b6, 0x2191, 0x2193, + 0x222b, 'x', 176, 184, 183, 0x22ba, 179, 'F', + + 0x221a, 180, 178, 0x2220, 176, 0x2b3, 0x22ba, 0x2264, + 0x2260, 0x2265, 0x2212, 0xd875dda4,0x2192,'?', 0x2191, 0x2193, + + ' ', '!', '\"', '#', 0x2074, '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x3b8, '\\', ']', '^', '_', + + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', '=', + + 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087, + 0x2088, 0x2089, 192+1, 192+0, 192+2, 192+4, 224+1, 224+0, + + 224+2, 224+4, 200+1, 200+0, 200+2, 200+4, 231+1, 231+0, + 231+2, 231+4, 204+1, 204+0, 204+2, 204+3, 236+1, 236+0, + + 236+2, 236+3, 210+1, 210+0, 210+2, 210+4, 242+1, 242+0, + 242+2, 242+4, 217+1, 217+0, 217+2, 217+3, 249+1, 249+0, + + 249+2, 249+3, 199, 231, 209, 204, '\'', '`', + 0x0a8, 0x0bf, 0x0a1, 0x3b1, 0x3b2, 0x3b3, 0x394, 0x3b4, + + 0x3b5, '[', 0x3bb, 0x3bc, 0x3c0, 0x3c1, 0x3a3, 0x3c3, + 0x3c4, 0x3d5, 0x3a9, 'x', 'y', '?', 0x2026, 0x25c0, + + 0x25fe, '?', 0x2212, 178, 176, 179, '\n', 0x3b7, + 0x25b6, '_', '_', '_', '_', '_', '_', '_', + + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', +]); diff --git a/src/character-encoding/ti83.js b/src/character-encoding/ti83.js new file mode 100644 index 0000000..42e9748 --- /dev/null +++ b/src/character-encoding/ti83.js @@ -0,0 +1,52 @@ +// Conversion table for going from TI characters to UTF16 +// Adapted from https://github.com/debrouxl/tilibs/blob/experimental2/libticonv/trunk/src/charset.cc + +module.exports = require('./normalize')([ + '\0', 0x3b7, 'u', 'v', 'w', 0x25b6, 0x2191, 0x2193, // [0x01-0x05] != TI83 + 0x222b, 'x', 176, 184, 183, 0x22ba, 179, 'F', + + 0x221a, 180, 178, 0x2220, 176, 0x2b3, 0x22ba, 0x2264, + 0x2260, 0x2265, 0x2212, 0xd875dda4,0x2192,'?', 0x2191, 0x2193, + + ' ', '!', '\"', '#', 0x2074, '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x3b8, '\\', ']', '^', '_', + + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', '=', + + 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087, + 0x2088, 0x2089, 192+1, 192+0, 192+2, 192+4, 224+1, 224+0, + + 224+2, 224+4, 200+1, 200+0, 200+2, 200+4, 231+1, 231+0, + 231+2, 231+4, 204+1, 204+0, 204+2, 204+3, 236+1, 236+0, + + 236+2, 236+3, 210+1, 210+0, 210+2, 210+4, 242+1, 242+0, + 242+2, 242+4, 217+1, 217+0, 217+2, 217+3, 249+1, 249+0, + + 249+2, 249+3, 199, 231, 209, 204, '\'', '`', + 0x0a8, 0x0bf, 0x0a1, 0x3b1, 0x3b2, 0x3b3, 0x394, 0x3b4, + + 0x3b5, '[', 0x3bb, 0x3bc, 0x3c0, 0x3c1, 0x3a3, 0x3c3, + 0x3c4, 0x3d5, 0x3a9, 'x', 'y', '?', 0x2026, 0x25c0, + + 0x25fe, '?', 0x2212, 178, 176, 179, '\n', 0xd875dc8a, + '?', 0x3c7, 'F', 0x212f, 'L', 'N', '_' /*))*/,0x2192, + + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', +]); diff --git a/src/character-encoding/ti85.js b/src/character-encoding/ti85.js new file mode 100644 index 0000000..0928103 --- /dev/null +++ b/src/character-encoding/ti85.js @@ -0,0 +1,52 @@ +// Conversion table for going from TI characters to UTF16 +// Adapted from https://github.com/debrouxl/tilibs/blob/experimental2/libticonv/trunk/src/charset.cc + +module.exports = require('./normalize')([ + '\0', 'b', 'o', 'd', 'h', 0x25b6, 0x2191, 0x2193, + 0x222b, 'x', 'A', 'B', 'C', 'D', 'E', 'F', + + 0x221a, 180, 178, 0x2220, 176, 0x2b3, 0x22ba, 0x2264, + 0x2260, 0x2265, 0x2212, 0xd875dda4,0x2192,'?', 0x2191, 0x2193, + + ' ', '!', '\"', '#', 0x2074, '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', + + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', '=', + + 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087, + 0x2088, 0x2089, 192+1, 192+0, 192+2, 192+4, 224+1, 224+0, + + 224+2, 224+4, 200+1, 200+0, 200+2, 200+4, 231+1, 231+0, + 231+2, 231+4, 204+1, 204+0, 204+2, 204+3, 236+1, 236+0, + + 236+2, 236+3, 210+1, 210+0, 210+2, 210+4, 242+1, 242+0, + 242+2, 242+4, 217+1, 217+0, 217+2, 217+3, 249+1, 249+0, + + 249+2, 249+3, 199, 231, 209, 204, '\'', '`', + 0x0a8, 0x0bf, 0x0a1, 0x3b1, 0x3b2, 0x3b3, 0x394, 0x3b4, + + 0x3b5, 0x3b8, 0x3bb, 0x3bc, 0x3c0, 0x3c1, 0x3a3, 0x3c3, + 0x3c4, 0x3d5, 0x3a9, 'x', 'y', '?', 0x2026, 0x25c0, + + 0x25fe, '?', 0x2212, 178, 176, 179, '\n', 0x26b6, + '_', '_', '_', '_', '_', '_', '_', '_', + + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', +]); diff --git a/src/character-encoding/ti86.js b/src/character-encoding/ti86.js new file mode 100644 index 0000000..49fecb7 --- /dev/null +++ b/src/character-encoding/ti86.js @@ -0,0 +1,52 @@ +// Conversion table for going from TI characters to UTF16 +// Adapted from https://github.com/debrouxl/tilibs/blob/experimental2/libticonv/trunk/src/charset.cc + +module.exports = require('./normalize')([ + '\0', 'b', 'o', 'd', 'h', 0x25b6, 0x2191, 0x2193, + 0x222b, 'x', 'A', 'B', 'C', 'D', 'E', 'F', + + 0x221a, 180, 178, 0x2220, 176, 0x2b3, 0x22ba, 0x2264, + 0x2260, 0x2265, 0x2212, 0xd875dda4,0x2192,'?', 0x2191, 0x2193, + + ' ', '!', '\"', '#', 0x2074, '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', // TI82 != TI85: theta <-> [ + + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', '=', + + 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087, + 0x2088, 0x2089, 192+1, 192+0, 192+2, 192+4, 224+1, 224+0, + + 224+2, 224+4, 200+1, 200+0, 200+2, 200+4, 231+1, 231+0, + 231+2, 231+4, 204+1, 204+0, 204+2, 204+3, 236+1, 236+0, + + 236+2, 236+3, 210+1, 210+0, 210+2, 210+4, 242+1, 242+0, + 242+2, 242+4, 217+1, 217+0, 217+2, 217+3, 249+1, 249+0, + + 249+2, 249+3, 199, 231, 209, 204, '\'', '`', + 0x0a8, 0x0bf, 0x0a1, 0x3b1, 0x3b2, 0x3b3, 0x394, 0x3b4, + + 0x3b5, 0x3b8, 0x3bb, 0x3bc, 0x3c0, 0x3c1, 0x3a3, 0x3c3, + 0x3c4, 0x3d5, 0x3a9, 0x00780305, 0x00790305, '?', 0x2026, 0x25c0, + + 0x25fe, '?', 0x2212, 178, 176, 179, '\n', 0x26b6, + '_', '_', '_', '_', '_', '_', '_', '_', + + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', +]); diff --git a/src/character-encoding/ti8x+.js b/src/character-encoding/ti8x+.js new file mode 100644 index 0000000..cf27c69 --- /dev/null +++ b/src/character-encoding/ti8x+.js @@ -0,0 +1,53 @@ +// Conversion table for going from TI characters to UTF16 +// TI-83+ / TI-84+ +// Adapted from https://github.com/debrouxl/tilibs/blob/experimental2/libticonv/trunk/src/charset.cc + +module.exports = require('./normalize')([ + '\0', 0x3b7, 'u', 'v', 'w', 0x25b6, 0x2191, 0x2193, // [0x01-0x05] != TI83 + 0x222b, 215, 176, 184, 183, 0x22ba, 179, 'F', + + 0x221a, 180, 178, 0x2220, 176, 0x2b3, 0x22ba, 0x2264, + 0x2260, 0x2265, 0x2212, 0xd875dda4,0x2192,'?', 0x2191, 0x2193, + + ' ', '!', '\"', '#', 0x2074, '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x3b8, '\\', ']', '^', '_', + + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', '=', + + 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085, 0x2086, 0x2087, + 0x2088, 0x2089, 192+1, 192+0, 192+2, 192+4, 224+1, 224+0, + + 224+2, 224+4, 200+1, 200+0, 200+2, 200+3, 232+1, 232+0, + 232+2, 232+3, 204+1, 204+0, 204+2, 204+3, 236+1, 236+0, + + 236+2, 236+3, 210+1, 210+0, 210+2, 210+4, 242+1, 242+0, + 242+2, 242+4, 217+1, 217+0, 217+2, 217+3, 249+1, 249+0, + + 249+2, 249+3, 199, 231, 209, 241, '\'', '`', + 0x0a8, 0x0bf, 0x0a1, 0x3b1, 0x3b2, 0x3b3, 0x394, 0x3b4, + + 0x3b5, '[', 0x3bb, 0x3bc, 0x3c0, 0x3c1, 0x3a3, 0x3c3, + 0x3c4, 0x3d5, 0x3a9, 0x00780305, 0x00790305, 0xa4, 0x2026, 0x25c0, + + 0x25fe, '?', 0x2212, 178, 176, 179, '\n', 0xd875dc8a, + '?', 0x3c7, 'F', 0x212f, 'L', 'N', '_', 0x2192, + + '_', '_', '_', '_', '_', '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', + + '_', '_', '$', '_', 223, '_', '_', '_', + '_', '_', '_', '_', '_', '_', '_', '_', +]); diff --git a/src/character-encoding/ti9x.js b/src/character-encoding/ti9x.js new file mode 100644 index 0000000..5d7d284 --- /dev/null +++ b/src/character-encoding/ti9x.js @@ -0,0 +1,107 @@ +// Conversion table for going from TI characters to UTF16 +// TI89, 92, 92+, V200, Titanium +// Adapted from https://github.com/debrouxl/tilibs/blob/experimental2/libticonv/trunk/src/charset.cc + +module.exports = require('./normalize')([ +// control chars + 0, // 0x2592 is prettier + 1, // 0x2401 is prettier + 2, // 0x2402 is prettier + 3, // 0x2403 is prettier + 4, // 0x2404 is prettier + 5, // 0x2405 is prettier + 6, // 0x2406 is prettier + 7, // 0x2407, 0xd83ddd14 are prettier + 8, // 0x232b is prettier + 9, // 0x21e5 is prettier + 10, // 0x21b4 is prettier + 0x2934, + 12, // 0x219f (upwards version of 0x21a1 form feed) is prettier + 13, // 0x21b5 is prettier + 0x2693, // For now, using anchor symbol U+2693 to represent locked, but should switch to 0xd83ddd12 (U+1F512) when Unicode 6.0+ is more widely implemented. + 0x2713, + 0x25fe, + 0x25c2, + 0x25b8, + 0x25b4, + 0x25be, + 0x2190, + 0x2192, + 0x2191, + 0x2193, + 0x25c0, + 0x25b6, + 0x2b06, + 0x222a, + 0x2229, + 0x2282, + 0x2208, +// ASCII + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 0x25c6, + +// Greek letters + 0x3b1, 0x3b2, 0x393, 0x3b3, 0x394, 0x3b4, 0x3b5, 0x3b6, 0x3b8, 0x3bb, 0x3be, 0x3a0, 0x3c0, 0x3c1, 0x3a3, 0x3c3, + 0x3c4, + 0x3c6, + 0x3c8, + 0x3a9, + 0x3c9, +// Math symbols + 0xd875dda4, //E (non-BMP character) + 0x212f, //e + 0xd875dc8a, //i (non-BMP character) + 0x2b3, //r + 0x22ba, //T - questionable. + 0x00780305, //x bar (requires composition) + 0x00790305, //y bar (requires composition) + 0x2264, + 0x2260, + 0x2265, + 0x2220, +// Latin1 + 0x2026, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 0x221a, + 169, + 170, //^g in AMS 3.10, but there is no such character in Unicode + 171, + 172, + 0x2212, + 174, + 175, + 176, + 177, + 178, + 179, + 180, //^-1, but there is no such character in Unicode 0xB9 is superscript 1 + 181, + 182, + 183, + 0x207a, + 185, + 186, + 187, + 0x2202, + 0x222b, + 0x221e, + 191, + + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 +]); diff --git a/test/character-encoding/convert.test.js b/test/character-encoding/convert.test.js new file mode 100644 index 0000000..d2e5a6b --- /dev/null +++ b/test/character-encoding/convert.test.js @@ -0,0 +1,24 @@ +const c = require('../../src/character-encoding/convert'); +const ti8x = require('../../src/character-encoding/ti8x+'); + +describe('Character encoding conversion', () => { + + describe('can go from TI encoding to UTF16', () => { + it("doesn't mess up alphabetic characters", () => { + expect(c.toUTF16(ti8x, "Hello")).toEqual("Hello"); + }); + it("can handle some special characters", () => { + expect(c.toUTF16(ti8x, "»")).toEqual("α"); + }); + }); + + describe('can go from UTF16 to TI encoding', () => { + it("doesn't mess up alphabetic characters", () => { + expect(c.fromUTF16(ti8x, "Hello")).toEqual("Hello"); + }); + it("can handle some special characters", () => { + expect(c.fromUTF16(ti8x, "α")).toEqual("»"); + }); + }); + +}); From c333a64d3b6c31c34e89e3497d4d406e17c8ee95 Mon Sep 17 00:00:00 2001 From: Timendus Date: Mon, 22 Nov 2021 23:27:33 +0100 Subject: [PATCH 2/5] Move all character encoding magic to 'convert' --- src/byte-mangling.js | 28 ++------ src/character-encoding/convert.js | 58 ++++++++++------ test/byte-mangling.test.js | 46 ------------- test/character-encoding/convert.test.js | 90 ++++++++++++++++++++++--- 4 files changed, 125 insertions(+), 97 deletions(-) diff --git a/src/byte-mangling.js b/src/byte-mangling.js index c3c5e90..2bf0d7c 100644 --- a/src/byte-mangling.js +++ b/src/byte-mangling.js @@ -10,8 +10,7 @@ module.exports = { intToBytes, bytesToInt, - asciiToBytes, - bytesToAscii, + zeroTerminate, chunkArray } @@ -156,25 +155,12 @@ function _bytesSafeInteger(bytes) { return false; } -function asciiToBytes(string, length) { - length = length || string.length + 1; - const TE = typeof TextEncoder !== 'undefined' ? TextEncoder : require('util').TextEncoder; - const bytes = new TE("utf-8").encode(string); - const result = new Uint8Array(length); - result.set(bytes.slice(0,length)); - return result; -} - -function bytesToAscii(bytes) { - // A string can be zero-terminated. Make sure we respect that - const index = bytes.indexOf(0); - if ( index >= 0 ) { - bytes = bytes.slice(0, index); - } - - // Interpret the rest as UTF-8 bytes - const TD = typeof TextDecoder !== 'undefined' ? TextDecoder : require('util').TextDecoder; - return new TD("utf-8").decode(bytes); +// Terminate an array of bytes at the first zero, stripping off the zero and +// anything that may come after. If no zeroes are found, don't touch the input. +function zeroTerminate(bytes) { + const firstZero = bytes.indexOf(0); + if ( firstZero == -1 ) return bytes; + return bytes.slice(0, firstZero); } // Split up an array in pieces, each of a size defined in sizes. If we run out diff --git a/src/character-encoding/convert.js b/src/character-encoding/convert.js index a5f99e1..b1013a2 100644 --- a/src/character-encoding/convert.js +++ b/src/character-encoding/convert.js @@ -1,3 +1,12 @@ +// All the conversion magic for character encoding, to and from different +// formats and bytes + +module.exports = { + parseAsUTF, + parseAsTIChars, + UTFToBytes +}; + const charEncodings = { 'TI-73': require('./ti73'), 'TI-82': require('./ti82'), @@ -12,27 +21,36 @@ const charEncodings = { //'TI-CBL2': require(???), } -module.exports = { - // String in, string out - toUTF16: (charset, input) => - convert(charset, input, (cs, c) => cs[c]), - fromUTF16: (charset, input) => - convert(charset, input, (cs, c) => cs.indexOf(c)), +function parseAsUTF(bytes) { + // A string can be zero-terminated. Make sure we respect that + const index = bytes.indexOf(0); + if ( index >= 0 ) bytes = bytes.slice(0, index); - // Uint8Array in, string out - parse: (input, calcType) => { - let charset = charEncodings[calcType]; - if (!charset) return "Decoding error: can't decode strings for this calculator type"; - let output = ''; - for ( c of input ) { - output += String.fromCharCode(charset[c]); - } - return output; + // Interpret the rest as UTF-8 bytes + const TD = typeof TextDecoder !== 'undefined' ? TextDecoder : require('util').TextDecoder; + return new TD("utf8").decode(bytes); +} + +function parseAsTIChars(bytes, calcType) { + // A string can be zero-terminated. Make sure we respect that + const index = bytes.indexOf(0); + if ( index >= 0 ) bytes = bytes.slice(0, index); + + // Interpret the rest as a TI encoded string + const charset = charEncodings[calcType]; + if (!charset) return "Decoding error: can't decode strings for this calculator type"; + let output = ''; + for ( c of bytes ) { + output += String.fromCharCode(charset[c]); } -}; + return output; +} -function convert(charset, input, lookup) { - return input.split('') - .map(c => String.fromCharCode(lookup(charset, c.charCodeAt(0)))) - .join(''); +function UTFToBytes(string, length) { + length = length || string.length + 1; + const TE = typeof TextEncoder !== 'undefined' ? TextEncoder : require('util').TextEncoder; + const bytes = new TE("utf-8").encode(string); + const result = new Uint8Array(length); + result.set(bytes.slice(0,length)); + return result; } diff --git a/test/byte-mangling.test.js b/test/byte-mangling.test.js index 4b55c03..7f795b8 100644 --- a/test/byte-mangling.test.js +++ b/test/byte-mangling.test.js @@ -159,52 +159,6 @@ describe('byte-mangling.js', () => { }); }); - describe('asciiToBytes', () => { - it('converts a string to a zero terminated Uint8Array', () => { - expect(b.asciiToBytes( - "Hello world" - )).toEqual( - new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0]) - ); - }); - it('converts a string to a Uint8Array of specified length', () => { - expect(b.asciiToBytes( - "Hello world", 14 - )).toEqual( - new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 0, 0]) - ); - expect(b.asciiToBytes( - "Hello world", 8 - )).toEqual( - new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111]) - ); - }); - }); - - describe('bytesToAscii', () => { - it('converts a zero terminated array to a string', () => { - expect(b.bytesToAscii( - new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0]) - )).toEqual( - "Hello world" - ); - }); - it('converts a non zero terminated array to a string', () => { - expect(b.bytesToAscii( - new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]) - )).toEqual( - "Hello world" - ); - }); - it('ignores crap after the zero terminator', () => { - expect(b.bytesToAscii( - new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 72, 101, 108, 111]) - )).toEqual( - "Hello world" - ); - }); - }); - }); describe('chunkArray', () => { diff --git a/test/character-encoding/convert.test.js b/test/character-encoding/convert.test.js index d2e5a6b..65c9612 100644 --- a/test/character-encoding/convert.test.js +++ b/test/character-encoding/convert.test.js @@ -3,21 +3,91 @@ const ti8x = require('../../src/character-encoding/ti8x+'); describe('Character encoding conversion', () => { - describe('can go from TI encoding to UTF16', () => { - it("doesn't mess up alphabetic characters", () => { - expect(c.toUTF16(ti8x, "Hello")).toEqual("Hello"); + describe('UTFToBytes', () => { + it('converts a string to a zero terminated Uint8Array', () => { + expect(c.UTFToBytes( + "Hello world" + )).toEqual( + new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0]) + ); }); - it("can handle some special characters", () => { - expect(c.toUTF16(ti8x, "»")).toEqual("α"); + it('converts a string to a Uint8Array of specified length', () => { + expect(c.UTFToBytes( + "Hello world", 14 + )).toEqual( + new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 0, 0]) + ); + expect(c.UTFToBytes( + "Hello world", 8 + )).toEqual( + new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111]) + ); }); }); - describe('can go from UTF16 to TI encoding', () => { - it("doesn't mess up alphabetic characters", () => { - expect(c.fromUTF16(ti8x, "Hello")).toEqual("Hello"); + describe('parseAsUTF', () => { + it('converts a zero terminated array to a string', () => { + expect(c.parseAsUTF( + new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0]) + )).toEqual( + "Hello world" + ); }); - it("can handle some special characters", () => { - expect(c.fromUTF16(ti8x, "α")).toEqual("»"); + it('converts a non zero terminated array to a string', () => { + expect(c.parseAsUTF( + new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]) + )).toEqual( + "Hello world" + ); + }); + it('ignores crap after the zero terminator', () => { + expect(c.parseAsUTF( + new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 72, 101, 108, 111]) + )).toEqual( + "Hello world" + ); + }); + it('treats special characters as UTF', () => { + expect(c.parseAsUTF( + new Uint8Array([0x5b, 0x7b, 0x40, 0x24]) + )).toEqual( + "[{@$" + ); + }); + }); + + describe('parseAsTIChars', () => { + it('converts a zero terminated array to a string', () => { + expect(c.parseAsTIChars( + new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0]), + 'TI-84 Plus' + )).toEqual( + "Hello world" + ); + }); + it('converts a non zero terminated array to a string', () => { + expect(c.parseAsTIChars( + new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]), + 'TI-84 Plus' + )).toEqual( + "Hello world" + ); + }); + it('ignores crap after the zero terminator', () => { + expect(c.parseAsTIChars( + new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 72, 101, 108, 111]), + 'TI-84 Plus' + )).toEqual( + "Hello world" + ); + }); + it('treats special characters as TI encoded', () => { + expect(c.parseAsTIChars( + new Uint8Array([0x5b, 0x7b, 0x40, 0x24]), + 'TI-84 Plus' + )).toEqual( + "θ{@⁴" + ); }); }); From 777e6f876b7a43d14d5b61bc2ab8f6c4b85eb167 Mon Sep 17 00:00:00 2001 From: Timendus Date: Mon, 22 Nov 2021 23:28:12 +0100 Subject: [PATCH 3/5] Add characterEncoding property to calculator type definitions --- src/calculators/ez80/ti83pce.js | 3 +++ src/calculators/ez80/ti83pceep.js | 3 +++ src/calculators/ez80/ti84pce.js | 3 +++ src/calculators/ez80/ti84pcet.js | 3 +++ src/calculators/ez80/ti84pcetpe.js | 3 +++ src/calculators/z80/ti82a.js | 3 +++ src/calculators/z80/ti84p.js | 3 +++ src/calculators/z80/ti84pcse.js | 3 +++ src/calculators/z80/ti84pse.js | 3 +++ src/calculators/z80/ti84pt.js | 3 +++ 10 files changed, 30 insertions(+) diff --git a/src/calculators/ez80/ti83pce.js b/src/calculators/ez80/ti83pce.js index e92dcd3..510df44 100644 --- a/src/calculators/ez80/ti83pce.js +++ b/src/calculators/ez80/ti83pce.js @@ -16,6 +16,9 @@ const properties = { productName: "TI-83 Premium CE" }, + // This is the character encoding scheme that the device expects + characterEncoding: 'TI-84 Plus', + // These are the file types we can send this particular device compatibleFiles: [ 'TI-83', diff --git a/src/calculators/ez80/ti83pceep.js b/src/calculators/ez80/ti83pceep.js index 7db4e58..58c6208 100644 --- a/src/calculators/ez80/ti83pceep.js +++ b/src/calculators/ez80/ti83pceep.js @@ -19,6 +19,9 @@ const properties = { productName: "TI-83 Premium CE" }, + // This is the character encoding scheme that the device expects + characterEncoding: 'TI-84 Plus', + // These are the file types we can send this particular device compatibleFiles: [ 'TI-83', diff --git a/src/calculators/ez80/ti84pce.js b/src/calculators/ez80/ti84pce.js index 5f6181c..dcb3b4e 100644 --- a/src/calculators/ez80/ti84pce.js +++ b/src/calculators/ez80/ti84pce.js @@ -16,6 +16,9 @@ const properties = { productName: "TI-84 Plus CE" }, + // This is the character encoding scheme that the device expects + characterEncoding: 'TI-84 Plus', + // These are the file types we can send this particular device compatibleFiles: [ 'TI-83', diff --git a/src/calculators/ez80/ti84pcet.js b/src/calculators/ez80/ti84pcet.js index c7b59c1..191260e 100644 --- a/src/calculators/ez80/ti84pcet.js +++ b/src/calculators/ez80/ti84pcet.js @@ -19,6 +19,9 @@ const properties = { productName: "TI-84 Plus CE" }, + // This is the character encoding scheme that the device expects + characterEncoding: 'TI-84 Plus', + // These are the file types we can send this particular device compatibleFiles: [ 'TI-83', diff --git a/src/calculators/ez80/ti84pcetpe.js b/src/calculators/ez80/ti84pcetpe.js index 2d065d3..3a51216 100644 --- a/src/calculators/ez80/ti84pcetpe.js +++ b/src/calculators/ez80/ti84pcetpe.js @@ -19,6 +19,9 @@ const properties = { productName: "TI-84 Plus CE" }, + // This is the character encoding scheme that the device expects + characterEncoding: 'TI-84 Plus', + // These are the file types we can send this particular device compatibleFiles: [ 'TI-83', diff --git a/src/calculators/z80/ti82a.js b/src/calculators/z80/ti82a.js index ad0a77a..9c2b808 100644 --- a/src/calculators/z80/ti82a.js +++ b/src/calculators/z80/ti82a.js @@ -16,6 +16,9 @@ const properties = { productName: "TI-82 Advanced" }, + // This is the character encoding scheme that the device expects + characterEncoding: 'TI-84 Plus', + // These are the file types we can send this particular device compatibleFiles: [ 'TI-83', diff --git a/src/calculators/z80/ti84p.js b/src/calculators/z80/ti84p.js index 7c82aac..dd6fe03 100644 --- a/src/calculators/z80/ti84p.js +++ b/src/calculators/z80/ti84p.js @@ -15,6 +15,9 @@ const properties = { productId: 0xe003 }, + // This is the character encoding scheme that the device expects + characterEncoding: 'TI-84 Plus', + // These are the file types we can send this particular device compatibleFiles: [ 'TI-83', diff --git a/src/calculators/z80/ti84pcse.js b/src/calculators/z80/ti84pcse.js index 7114216..f0ed40e 100644 --- a/src/calculators/z80/ti84pcse.js +++ b/src/calculators/z80/ti84pcse.js @@ -16,6 +16,9 @@ const properties = { productName: "TI-84 Plus C Silver Edition" }, + // This is the character encoding scheme that the device expects + characterEncoding: 'TI-84 Plus', + // These are the file types we can send this particular device compatibleFiles: [ 'TI-83', diff --git a/src/calculators/z80/ti84pse.js b/src/calculators/z80/ti84pse.js index e724e4b..0781fd5 100644 --- a/src/calculators/z80/ti84pse.js +++ b/src/calculators/z80/ti84pse.js @@ -16,6 +16,9 @@ const properties = { productName: "TI-84 Plus Silver Edition" }, + // This is the character encoding scheme that the device expects + characterEncoding: 'TI-84 Plus', + // These are the file types we can send this particular device compatibleFiles: [ 'TI-83', diff --git a/src/calculators/z80/ti84pt.js b/src/calculators/z80/ti84pt.js index 9d49d2a..18d4d1e 100644 --- a/src/calculators/z80/ti84pt.js +++ b/src/calculators/z80/ti84pt.js @@ -16,6 +16,9 @@ const properties = { productName: "TI-84 Plus T" }, + // This is the character encoding scheme that the device expects + characterEncoding: 'TI-84 Plus', + // These are the file types we can send this particular device compatibleFiles: [ 'TI-83', From 2a2c465a18435a1220af3faaacc186b746797a09 Mon Sep 17 00:00:00 2001 From: Timendus Date: Mon, 22 Nov 2021 23:29:21 +0100 Subject: [PATCH 4/5] Use new character encoding functions and calc property to properly parse entry names and comments --- src/dusb/ti84series.js | 10 ++++++++-- src/tifiles.js | 8 +++++--- test/tifiles.test.js | 38 +++++++++++++++++++------------------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/dusb/ti84series.js b/src/dusb/ti84series.js index 2cac241..7bef9ed 100644 --- a/src/dusb/ti84series.js +++ b/src/dusb/ti84series.js @@ -1,6 +1,7 @@ const Device = require('../dusb/device'); const v = require('../dusb/magic-values'); const b = require('../byte-mangling'); +const c = require('../character-encoding/convert'); module.exports = class Ti84series { @@ -92,11 +93,16 @@ module.exports = class Ti84series { } async _sendEntry(entry) { + // Convert TI file character encoding to this device's character encoding + // and then convert that to an array of bytes + let entryName = c.parseAsTIChars(entry.name, this.characterEncoding); + entryName = c.UTFToBytes(entryName, entryName.length); + await this._d.send({ type: v.virtualPacketTypes.DUSB_VPKT_RTS, data: [ - ...b.intToBytes(entry.name.length, 2), - ...b.asciiToBytes(entry.name, entry.name.length), 0, + ...b.intToBytes(entryName.length, 2), + ...entryName, 0, ...b.intToBytes(entry.size, 4), v.transferModes.SILENT, ...this._entryParameters(entry) diff --git a/src/tifiles.js b/src/tifiles.js index a8cc6b0..3a56113 100644 --- a/src/tifiles.js +++ b/src/tifiles.js @@ -2,6 +2,7 @@ // Inspired by tilibs (https://github.com/debrouxl/tilibs) const b = require('./byte-mangling'); +const c = require('./character-encoding/convert'); module.exports = { @@ -23,7 +24,7 @@ module.exports = { return { calcType, size, - comments: b.bytesToAscii(file.slice(11, 53)), + comments: c.parseAsTIChars(file.slice(11, 53), calcType), entries: findEntries(file.slice(55), { size, calcType }), debug: { signature: getSignature(file.slice(8,11)), @@ -55,7 +56,7 @@ function getCalcType(bytes) { '**V200**': 'TI-V200', '**TICBL*': 'TI-CBL2' }; - return headers[b.bytesToAscii(bytes)] || 'NONE'; + return headers[c.parseAsUTF(bytes)] || 'NONE'; } function findEntries(bytes, file) { @@ -90,7 +91,8 @@ function getEntry(bytes, file) { const size = b.bytesToInt(bytes.slice(2, 4).reverse()); return { - name: b.bytesToAscii(header.name), + displayName: c.parseAsTIChars(header.name, file.calcType), + name: b.zeroTerminate(header.name), type: bytes[4], attributes: header.attributes, size, diff --git a/test/tifiles.test.js b/test/tifiles.test.js index 4c8ad01..4ed2424 100644 --- a/test/tifiles.test.js +++ b/test/tifiles.test.js @@ -80,7 +80,7 @@ describe('tifiles.js', () => { size: 731, entries: [ { - name: 'ROMDUMP', + displayName: 'ROMDUMP', type: 6, size: 716 } @@ -101,17 +101,17 @@ describe('tifiles.js', () => { size: 1451, entries: [ { - name: 'BOGGLE', + displayName: 'BOGGLE', type: 5, size: 1159 }, { - name: ']BOGGL', + displayName: ']BOGGL', type: 1, size: 11 }, { - name: ']ASCII', + displayName: ']ASCII', type: 13, size: 236 } @@ -136,7 +136,7 @@ describe('tifiles.js', () => { size: 116, entries: [ { - name: 'TVA', // Not sure if this is right + displayName: 'TVA', // Not sure if this is right type: 5, // But it could be ;) size: 101 } @@ -157,12 +157,12 @@ describe('tifiles.js', () => { size: 48, entries: [ { - name: 'A', + displayName: 'A', type: 0, size: 9 }, { - name: 'B', + displayName: 'B', type: 0, size: 9 } @@ -187,7 +187,7 @@ describe('tifiles.js', () => { size: 721, entries: [ { - name: 'ROMDUMP', + displayName: 'ROMDUMP', type: 6, size: 706 } @@ -208,12 +208,12 @@ describe('tifiles.js', () => { size: 48, entries: [ { - name: 'A', + displayName: 'A', type: 0, size: 9 }, { - name: 'B', + displayName: 'B', type: 0, size: 9 } @@ -238,7 +238,7 @@ describe('tifiles.js', () => { size: 438, entries: [ { - name: 'ROMDUMP', + displayName: 'ROMDUMP', type: 6, size: 421 } @@ -259,12 +259,12 @@ describe('tifiles.js', () => { size: 52, entries: [ { - name: 'A', + displayName: 'A', type: 0, size: 9 }, { - name: 'B', + displayName: 'B', type: 0, size: 9 } @@ -289,7 +289,7 @@ describe('tifiles.js', () => { size: 410, entries: [ { - name: 'FList', + displayName: 'FList', type: 18, size: 397 } @@ -310,12 +310,12 @@ describe('tifiles.js', () => { size: 38, entries: [ { - name: 'A', + displayName: 'A', type: 0, size: 10 }, { - name: 'B', + displayName: 'B', type: 0, size: 10 } @@ -340,7 +340,7 @@ describe('tifiles.js', () => { size: 707, entries: [ { - name: 'ROMDump', + displayName: 'ROMDump', type: 18, size: 692 } @@ -361,12 +361,12 @@ describe('tifiles.js', () => { size: 52, entries: [ { - name: 'Y', + displayName: 'Y', type: 0, size: 10 }, { - name: 'X', + displayName: 'X', type: 0, size: 10 } From 5c6a00cb4a706bf7c7305adea08d8ad11f02ebaf Mon Sep 17 00:00:00 2001 From: Timendus Date: Mon, 22 Nov 2021 23:41:45 +0100 Subject: [PATCH 5/5] Don't mess with string length, just give it to us as is --- src/character-encoding/convert.js | 7 ++----- src/dusb/ti84series.js | 2 +- test/character-encoding/convert.test.js | 16 ++-------------- 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/character-encoding/convert.js b/src/character-encoding/convert.js index b1013a2..bda3b07 100644 --- a/src/character-encoding/convert.js +++ b/src/character-encoding/convert.js @@ -46,11 +46,8 @@ function parseAsTIChars(bytes, calcType) { return output; } -function UTFToBytes(string, length) { - length = length || string.length + 1; +function UTFToBytes(string) { const TE = typeof TextEncoder !== 'undefined' ? TextEncoder : require('util').TextEncoder; const bytes = new TE("utf-8").encode(string); - const result = new Uint8Array(length); - result.set(bytes.slice(0,length)); - return result; + return new Uint8Array(bytes); } diff --git a/src/dusb/ti84series.js b/src/dusb/ti84series.js index 7bef9ed..737bfa1 100644 --- a/src/dusb/ti84series.js +++ b/src/dusb/ti84series.js @@ -96,7 +96,7 @@ module.exports = class Ti84series { // Convert TI file character encoding to this device's character encoding // and then convert that to an array of bytes let entryName = c.parseAsTIChars(entry.name, this.characterEncoding); - entryName = c.UTFToBytes(entryName, entryName.length); + entryName = c.UTFToBytes(entryName); await this._d.send({ type: v.virtualPacketTypes.DUSB_VPKT_RTS, diff --git a/test/character-encoding/convert.test.js b/test/character-encoding/convert.test.js index 65c9612..521d4a2 100644 --- a/test/character-encoding/convert.test.js +++ b/test/character-encoding/convert.test.js @@ -4,23 +4,11 @@ const ti8x = require('../../src/character-encoding/ti8x+'); describe('Character encoding conversion', () => { describe('UTFToBytes', () => { - it('converts a string to a zero terminated Uint8Array', () => { + it('converts a string to a Uint8Array', () => { expect(c.UTFToBytes( "Hello world" )).toEqual( - new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0]) - ); - }); - it('converts a string to a Uint8Array of specified length', () => { - expect(c.UTFToBytes( - "Hello world", 14 - )).toEqual( - new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 0, 0]) - ); - expect(c.UTFToBytes( - "Hello world", 8 - )).toEqual( - new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111]) + new Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]) ); }); });