| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- const {
- normalizeTextValue
- } = require('../../utils/base-utils.js')
- const {
- trimTrailingNullBytes
- } = require('../../utils/binary-utils.js')
- const {
- MAX_TEXT_BYTE_LENGTH
- } = require('./constants.js')
- const {
- getDataType
- } = require('./value-types.js')
- function encodeAsciiBytes(text, byteLimit = 32) {
- const bytes = []
- const stringValue = normalizeTextValue(text)
- for (let index = 0; index < stringValue.length; index += 1) {
- const code = stringValue.charCodeAt(index)
- if (code > 0x7F) {
- throw new Error('ASCII 文本只能包含 0x00 - 0x7F 字符')
- }
- bytes.push(code)
- if (bytes.length > byteLimit) break
- }
- if (bytes.length > byteLimit) {
- throw new Error(`长文本最长 ${byteLimit} 字节`)
- }
- return bytes
- }
- function encodeUtf8Bytes(text, byteLimit = 32) {
- const bytes = []
- const encoded = encodeURIComponent(normalizeTextValue(text))
- for (let index = 0; index < encoded.length; index += 1) {
- const char = encoded[index]
- if (char === '%') {
- const byte = parseInt(encoded.slice(index + 1, index + 3), 16)
- if (!Number.isFinite(byte)) break
- bytes.push(byte & 0xFF)
- index += 2
- } else {
- bytes.push(char.charCodeAt(0) & 0xFF)
- }
- if (bytes.length > byteLimit) break
- }
- if (bytes.length > byteLimit) {
- throw new Error(`长文本最长 ${byteLimit} 字节`)
- }
- return bytes
- }
- function decodeAsciiBytes(bytes = []) {
- return String.fromCharCode.apply(null, trimTrailingNullBytes(bytes).map((byte) => byte & 0xFF))
- }
- function decodeUtf8Bytes(bytes = []) {
- const trimmed = trimTrailingNullBytes(bytes)
- if (!trimmed.length) return ''
- let encoded = ''
- trimmed.forEach((byte) => {
- encoded += `%${(byte & 0xFF).toString(16).padStart(2, '0').toUpperCase()}`
- })
- try {
- return decodeURIComponent(encoded)
- } catch (error) {
- return decodeAsciiBytes(trimmed)
- }
- }
- function encodeTextBytes(text, dataType, byteLimit = MAX_TEXT_BYTE_LENGTH) {
- const normalizedType = getDataType(dataType).key
- if (normalizedType === 'ascii') return encodeAsciiBytes(text, byteLimit)
- return encodeUtf8Bytes(text, byteLimit)
- }
- function decodeTextBytes(bytes, dataType) {
- const normalizedType = getDataType(dataType).key
- return normalizedType === 'ascii'
- ? decodeAsciiBytes(bytes)
- : decodeUtf8Bytes(bytes)
- }
- module.exports = {
- decodeAsciiBytes,
- decodeTextBytes,
- decodeUtf8Bytes,
- encodeAsciiBytes,
- encodeTextBytes,
- encodeUtf8Bytes
- }
|