All files / src/utils sjis-decode-encode.util.js

82.41% Statements 75/91
50% Branches 8/16
100% Functions 3/3
82.41% Lines 75/91

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 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 921x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 97x 97x 97x 16x     16x 16x 16x 16x 16x 16x             16x 16x 16x   16x 16x   16x 16x     16x 16x 16x 16x 4x 4x 4x 4x     4x 16x 12x 12x 12x 12x     12x 12x 16x 16x 16x 16x 97x 81x 81x 97x 10x 10x 10x  
import { textToBytes } from './text-decode-encode.util.js'
import { getUtf8ToJisTable } from './utf8-to-jis-table.js'
const sjisDecoder = new TextDecoder('sjis')
 
/**
 * @param {string} str - input text
 * @returns {Uint8Array} SJIS encoded byte array
 */
export const textToSjisBytes = (str) => UTF8ToSJIS(textToBytes(str))
 
/**
 * @param {Uint8Array} bytes - SJIS encoded byte array
 * @returns {string} decoded output
 */
export const sjisBytesToText = (bytes) => sjisDecoder.decode(bytes)
 
/**
 * Converts UTF-8 byte array to SJIS byte array
 * @param {Uint8Array} data - utf8 encoded byte array
 * @returns {Uint8Array} SJIS encoded byte array
 */
function UTF8ToSJIS (data) {
  const FALLBACK_CHARACTER = 63 // '?'
  const UTF8_TO_JIS_TABLE = getUtf8ToJisTable()
 
  /** @type {number[]} */
  const results = []
  const len = data.length
  let b1, b2, utf8, jis
 
  for (let i = 0; i < len; i++) {
    const b = data[i]
 
    if (b >= 0x80) {
      if (b <= 0xDF) {
        // 2 bytes
        utf8 = (b << 8) + data[++i]
      } else if (b <= 0xEF) {
        // 3 bytes
        utf8 = (b << 16) +
               (data[++i] << 8) +
               (data[++i] & 0xFF)
      } else {
        // 4 bytes
        utf8 = (b << 24) +
               (data[++i] << 16) +
               (data[++i] << 8) +
               (data[++i] & 0xFF)
      }
 
      jis = UTF8_TO_JIS_TABLE[utf8]
      if (jis == null) {
        results[results.length] = FALLBACK_CHARACTER
      } else {
        if (jis < 0xFF) {
          results[results.length] = jis + 0x80
        } else {
          if (jis > 0x10000) {
            jis -= 0x10000
          }
 
          b1 = jis >> 8
          b2 = jis & 0xFF
          if (b1 & 0x01) {
            b1 >>= 1
            if (b1 < 0x2F) {
              b1 += 0x71
            } else {
              b1 -= 0x4F
            }
            b2 += b2 > 0x5F ? 0x20 : 0x1F
          } else {
            b1 >>= 1
            if (b1 <= 0x2F) {
              b1 += 0x70
            } else {
              b1 -= 0x50
            }
            b2 += 0x7E
          }
          results[results.length] = b1 & 0xFF
          results[results.length] = b2 & 0xFF
        }
      }
    } else {
      results[results.length] = data[i] & 0xFF
    }
  }
 
  return Uint8Array.from(results)
}