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 }