1
0
mirror of synced 2026-05-22 14:43:19 +00:00

Replace text-coded with @exodus/bytes for text encoding and decoding

This commit is contained in:
Borewit
2026-02-21 16:11:14 +01:00
parent 50eed638b9
commit c619ac4a5a
11 changed files with 36 additions and 25 deletions
+2 -2
View File
@@ -18,7 +18,7 @@ import {
} from './APEv2Token.js';
import { makeUnexpectedFileContentError } from '../ParseError.js';
import type { IRandomAccessTokenizer } from 'strtok3';
import { textDecode } from '@borewit/text-codec';
import { TextDecoder } from '@exodus/bytes/encoding.js';
const debug = initDebug('music-metadata:parser:APEv2');
@@ -172,7 +172,7 @@ export class APEv2Parser extends BasicParser {
await this.tokenizer.readBuffer(picData);
zero = util.findZero(picData);
const description = textDecode(picData.subarray(0, zero), 'utf-8');
const description = new TextDecoder('utf-8').decode(picData.subarray(0, zero));
const data = picData.subarray(zero + 1);
await this.metadata.addTag(tagFormat, key, {
+3 -3
View File
@@ -1,5 +1,5 @@
import type { IToken } from 'strtok3';
import { textDecode, textEncode } from '@borewit/text-codec';
import { latin1toString, latin1fromString } from '@exodus/bytes/single-byte.js';
import * as util from './Util.js';
import { InternalParserError, FieldDecodingError } from '../ParseError.js';
@@ -14,7 +14,7 @@ export const FourCcToken: IToken<string> = {
len: 4,
get: (buf: Uint8Array, off: number): string => {
const id = textDecode(buf.subarray(off, off + FourCcToken.len), 'latin1');
const id = latin1toString(buf.subarray(off, off + FourCcToken.len));
if (!id.match(validFourCC)) {
throw new FieldDecodingError(`FourCC contains invalid characters: ${util.a2hex(id)} "${id}"`);
}
@@ -22,7 +22,7 @@ export const FourCcToken: IToken<string> = {
},
put: (buffer: Uint8Array, offset: number, id: string) => {
const str = textEncode(id, 'latin1');
const str = latin1fromString(id);
if (str.length !== 4)
throw new InternalParserError('Invalid length');
buffer.set(str, offset);
+2 -2
View File
@@ -9,7 +9,7 @@ import { APEv2Parser } from '../apev2/APEv2Parser.js';
import type { AnyTagValue, IApeHeader, IPrivateOptions } from '../type.js';
import type { INativeMetadataCollector } from '../common/MetadataCollector.js';
import { textDecode } from '@borewit/text-codec';
import { latin1toString } from '@exodus/bytes/single-byte.js';
const debug = initDebug('music-metadata:parser:ID3v1');
@@ -173,7 +173,7 @@ export async function hasID3v1Header(tokenizer: IRandomAccessTokenizer): Promise
const position = tokenizer.position;
await tokenizer.readBuffer(tag, {position: tokenizer.fileInfo.size - 128});
tokenizer.setPosition(position); // Restore tokenizer position
return textDecode(tag, 'latin1') === 'TAG';
return latin1toString(tag) === 'TAG';
}
return false;
}
+3 -3
View File
@@ -3,7 +3,7 @@ import * as Token from 'token-types';
import * as util from '../common/Util.js';
import { UINT32SYNCSAFE, type ID3v2MajorVersion } from './ID3v2Token.js';
import type { IWarningCollector } from '../common/MetadataCollector.js';
import { textDecode } from '@borewit/text-codec';
import { TextDecoder } from '@exodus/bytes/encoding.js';
import { Id3v2ContentError } from './FrameParser.js';
export interface IFrameFlags {
@@ -77,7 +77,7 @@ export function readFrameHeader(uint8Array: Uint8Array, majorVer: ID3v2MajorVers
function parseFrameHeaderV22(uint8Array: Uint8Array, majorVer: 2, warningCollector: IWarningCollector): IFrameHeader {
const header: IFrameHeader = {
id: textDecode(uint8Array.subarray(0, 3), 'ascii'),
id: new TextDecoder('ascii').decode(uint8Array.subarray(0, 3)),
length: Token.UINT24_BE.get(uint8Array, 3)
};
@@ -90,7 +90,7 @@ function parseFrameHeaderV22(uint8Array: Uint8Array, majorVer: 2, warningCollect
function parseFrameHeaderV23V24(uint8Array: Uint8Array, majorVer: 3 | 4, warningCollector: IWarningCollector): IFrameHeader {
const header: IFrameHeader = {
id: textDecode(uint8Array.subarray(0, 4), 'ascii'),
id: new TextDecoder('ascii').decode(uint8Array.subarray(0, 4)),
length: (majorVer === 4 ? UINT32SYNCSAFE : Token.UINT32_BE).get(uint8Array, 4),
flags: readFrameFlags(uint8Array.subarray(8, 10))
};
+2 -2
View File
@@ -1,5 +1,5 @@
import type {IRandomAccessTokenizer} from 'strtok3';
import { textDecode } from '@borewit/text-codec';
import { latin1toString } from '@exodus/bytes/single-byte.js';
export const endTag2 = 'LYRICS200';
@@ -10,7 +10,7 @@ export async function getLyricsHeaderLength(tokenizer: IRandomAccessTokenizer):
const position = tokenizer.position;
await tokenizer.readBuffer(buf, {position: fileSize - 143});
tokenizer.setPosition(position); // Restore position
const txt = textDecode(buf, 'latin1');
const txt = latin1toString(buf);
const tag = txt.substring(6);
if (tag === endTag2) {
return Number.parseInt(txt.substring(0, 6), 10) + 15;
+4 -4
View File
@@ -11,7 +11,7 @@ import { type AnyTagValue, type IChapter, type ITrackInfo, TrackType } from '../
import type { IGetToken } from '@tokenizer/token';
import { uint8ArrayToHex } from 'uint8array-extras';
import { textDecode } from '@borewit/text-codec';
import { TextDecoder } from '@exodus/bytes/encoding.js';
const debug = initDebug('music-metadata:parser:MP4');
const tagFormat = 'iTunes';
@@ -380,7 +380,7 @@ export class MP4Parser extends BasicParser {
default: {
const uint8Array = await this.tokenizer.readToken<Uint8Array>(new Token.Uint8ArrayType(payLoadLength));
this.addWarning(`Unsupported meta-item: ${tagKey}[${child.header.name}] => value=${uint8ArrayToHex(uint8Array)} ascii=${textDecode(uint8Array, 'ascii')}`);
this.addWarning(`Unsupported meta-item: ${tagKey}[${child.header.name}] => value=${uint8ArrayToHex(uint8Array)} ascii=${new TextDecoder('ascii').decode(uint8Array)}`);
}
}
@@ -418,7 +418,7 @@ export class MP4Parser extends BasicParser {
}
case 'rate': {
const rate = textDecode(dataAtom.value, 'ascii');
const rate = new TextDecoder('ascii').decode(dataAtom.value);
await this.addTag(tagKey, rate);
break;
}
@@ -430,7 +430,7 @@ export class MP4Parser extends BasicParser {
case 1: // UTF-8: Without any count or NULL terminator
case 18: // Unknown: Found in m4b in combination with a '©gen' tag
await this.addTag(tagKey, textDecode(dataAtom.value));
await this.addTag(tagKey, new TextDecoder().decode(dataAtom.value));
break;
case 13: // JPEG
+2 -3
View File
@@ -1,8 +1,7 @@
import * as Token from 'token-types';
import type { IGetToken } from 'strtok3';
import * as util from '../../common/Util.js';
import { textDecode } from '@borewit/text-codec';
import { latin1toString } from '@exodus/bytes/single-byte.js';
/**
* MusePack stream version 7 format specification
@@ -45,7 +44,7 @@ export const Header: IGetToken<IHeader> = {
const header = {
// word 0
signature: textDecode(buf.subarray(off, off + 3), 'latin1'),
signature: latin1toString(buf.subarray(off, off + 3)),
// versionIndex number * 1000 (3.81 = 3810) (remember that 4-byte alignment causes this to take 4-bytes)
streamMinorVersion: util.getBitAllignedNumber(buf, off + 3, 0, 4),
streamMajorVersion: util.getBitAllignedNumber(buf, off + 3, 4, 4),
+2 -2
View File
@@ -1,5 +1,5 @@
import * as Token from 'token-types';
import { textDecode } from '@borewit/text-codec';
import { TextDecoder } from '@exodus/bytes/encoding.js';
export class VorbisDecoder {
private readonly data: Uint8Array;
@@ -19,7 +19,7 @@ export class VorbisDecoder {
public readStringUtf8(): string {
const len = this.readInt32();
const value = textDecode(this.data.subarray(this.offset, this.offset + len), 'utf-8');
const value = new TextDecoder().decode(this.data.subarray(this.offset, this.offset + len));
this.offset += len;
return value;
}
+1 -1
View File
@@ -108,7 +108,7 @@
"update-biome": "yarn add -D --exact @biomejs/biome && npx @biomejs/biome migrate --write"
},
"dependencies": {
"@borewit/text-codec": "^0.2.1",
"@exodus/bytes": "^1.14.1",
"@tokenizer/token": "^0.3.0",
"content-type": "^1.0.5",
"debug": "^4.4.3",
+2 -2
View File
@@ -3,7 +3,7 @@ import { assert } from 'chai';
import * as util from '../lib/common/Util.js';
import { FourCcToken } from '../lib/common/FourCC.js';
import { textDecode } from '@borewit/text-codec';
import { latin1toString } from '@exodus/bytes/single-byte.js';
const t = assert;
@@ -72,7 +72,7 @@ describe('shared utility functionality', () => {
it('should be able to encode FourCC token', () => {
const buffer = new Uint8Array(4);
FourCcToken.put(buffer, 0, 'abcd');
t.deepEqual(textDecode(buffer, 'latin1'), 'abcd');
t.deepEqual(latin1toString(buffer), 'abcd');
});
});
+13 -1
View File
@@ -144,6 +144,18 @@ __metadata:
languageName: node
linkType: hard
"@exodus/bytes@npm:^1.14.1":
version: 1.14.1
resolution: "@exodus/bytes@npm:1.14.1"
peerDependencies:
"@noble/hashes": ^1.8.0 || ^2.0.0
peerDependenciesMeta:
"@noble/hashes":
optional: true
checksum: 10c0/486dad30992a8c81058b6b59341ee934c10a7e8016b440770de0f86d2e270950c5d37fc6724ea017295b8654c7564abf6a21cc49bed569d74721b545f571e416
languageName: node
linkType: hard
"@isaacs/cliui@npm:^8.0.2":
version: 8.0.2
resolution: "@isaacs/cliui@npm:8.0.2"
@@ -2206,7 +2218,7 @@ __metadata:
resolution: "music-metadata@workspace:."
dependencies:
"@biomejs/biome": "npm:2.4.0"
"@borewit/text-codec": "npm:^0.2.1"
"@exodus/bytes": "npm:^1.14.1"
"@tokenizer/token": "npm:^0.3.0"
"@types/chai": "npm:^5.2.3"
"@types/chai-as-promised": "npm:^8.0.2"