From 156f5289c443d8aee5f40570ee9e2bf28e3b3df7 Mon Sep 17 00:00:00 2001 From: Borewit Date: Sat, 13 Mar 2021 17:11:43 +0100 Subject: [PATCH] Use Uint8Array instead of Buffer where reasonable possible --- lib/aiff/AiffParser.ts | 2 +- lib/apev2/APEv2Token.ts | 10 ++--- lib/asf/AsfObject.ts | 4 +- lib/asf/GUID.ts | 2 - lib/common/Util.ts | 4 +- lib/dsdiff/DsdiffParser.ts | 2 +- lib/flac/FlacParser.ts | 6 +-- lib/id3v1/ID3v1Parser.ts | 2 +- lib/id3v2/ID3v2Token.ts | 4 +- lib/iff/index.ts | 3 +- lib/mp4/AtomToken.ts | 8 ++-- lib/mpeg/MpegParser.ts | 2 +- lib/musepack/sv7/StreamVersion7.ts | 2 +- lib/ogg/Ogg.ts | 2 +- lib/ogg/OggParser.ts | 10 ++--- lib/ogg/speex/Speex.ts | 2 +- lib/ogg/theora/Theora.ts | 2 +- lib/ogg/vorbis/Vorbis.ts | 17 ++++---- lib/ogg/vorbis/VorbisDecoder.ts | 4 +- lib/riff/RiffChunk.ts | 4 +- lib/wav/WaveParser.ts | 2 +- lib/wavpack/WavPackToken.ts | 4 +- package.json | 5 ++- test/test-file-asf.ts | 68 ++++++++++++++++-------------- yarn.lock | 59 +++++++++++++++++++++++--- 25 files changed, 142 insertions(+), 88 deletions(-) diff --git a/lib/aiff/AiffParser.ts b/lib/aiff/AiffParser.ts index 653f285fc..640826cd9 100644 --- a/lib/aiff/AiffParser.ts +++ b/lib/aiff/AiffParser.ts @@ -80,7 +80,7 @@ export class AIFFParser extends BasicParser { return header.chunkSize; case 'ID3 ': // ID3-meta-data - const id3_data = await this.tokenizer.readToken(new Token.BufferType(header.chunkSize)); + const id3_data = await this.tokenizer.readToken(new Token.Uint8ArrayType(header.chunkSize)); const rst = strtok3.fromBuffer(id3_data); await new ID3v2Parser().parse(this.metadata, rst, this.options); return header.chunkSize; diff --git a/lib/apev2/APEv2Token.ts b/lib/apev2/APEv2Token.ts index fa82f60f4..aef83f547 100644 --- a/lib/apev2/APEv2Token.ts +++ b/lib/apev2/APEv2Token.ts @@ -44,7 +44,7 @@ export interface IDescriptor { // the terminating data of the file (not including tag data) terminatingDataBytes: number, // the MD5 hash of the file (see notes for usage... it's a littly tricky) - fileMD5: Buffer + fileMD5: Uint8Array } /** @@ -115,8 +115,8 @@ export const DescriptorParser: IGetToken = { apeFrameDataBytesHigh: Token.UINT32_LE.get(buf, off + 28), // the terminating data of the file (not including tag data) terminatingDataBytes: Token.UINT32_LE.get(buf, off + 32), - // the MD5 hash of the file (see notes for usage... it's a littly tricky) - fileMD5: new Token.BufferType(16).get(buf, off + 36) + // the MD5 hash of the file (see notes for usage... it's a little tricky) + fileMD5: new Token.Uint8ArrayType(16).get(buf, off + 36) }; } }; @@ -156,7 +156,7 @@ export const Header: IGetToken = { export const TagFooter: IGetToken = { len: 32, - get: (buf, off) => { + get: (buf: Buffer, off) => { return { // should equal 'APETAGEX' ID: new Token.StringType(8, 'ascii').get(buf, off), @@ -199,7 +199,7 @@ export const TagItemHeader: IGetToken = { }; export const TagField = footer => { - return new Token.BufferType(footer.size - TagFooter.len); + return new Token.Uint8ArrayType(footer.size - TagFooter.len); }; export interface ITagFlags { diff --git a/lib/asf/AsfObject.ts b/lib/asf/AsfObject.ts index 0041ba1f3..91ba9dbb0 100644 --- a/lib/asf/AsfObject.ts +++ b/lib/asf/AsfObject.ts @@ -66,7 +66,7 @@ export interface IAsfTopLevelObjectHeader extends IAsfObjectHeader { * Token for: 3. ASF top-level Header Object * Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3 */ -export const TopLevelHeaderObjectToken: IGetToken = { +export const TopLevelHeaderObjectToken: IGetToken = { len: 30, @@ -84,7 +84,7 @@ export const TopLevelHeaderObjectToken: IGetToken = { * Token for: 3.1 Header Object (mandatory, one only) * Ref: http://drang.s4.xrea.com/program/tips/id3tag/wmp/03_asf_top_level_header_object.html#3_1 */ -export const HeaderObjectToken: IGetToken = { +export const HeaderObjectToken: IGetToken = { len: 24, diff --git a/lib/asf/GUID.ts b/lib/asf/GUID.ts index e8a18b037..67aeb97ce 100644 --- a/lib/asf/GUID.ts +++ b/lib/asf/GUID.ts @@ -1,5 +1,3 @@ -// Implementation of the Advanced Systems Format (ASF) - /** * Ref: * https://tools.ietf.org/html/draft-fleischman-asf-01, Appendix A: ASF GUIDs diff --git a/lib/common/Util.ts b/lib/common/Util.ts index b89646a6f..7377f0a42 100644 --- a/lib/common/Util.ts +++ b/lib/common/Util.ts @@ -93,7 +93,7 @@ export function stripNulls(str: string): string { * @param len Length of number in bits * @return {number} decoded bit aligned number */ -export function getBitAllignedNumber(buf: Buffer, byteOffset: number, bitOffset: number, len: number): number { +export function getBitAllignedNumber(buf: Uint8Array, byteOffset: number, bitOffset: number, len: number): number { const byteOff = byteOffset + ~~(bitOffset / 8); const bitOff = bitOffset % 8; let value = buf[byteOff]; @@ -117,7 +117,7 @@ export function getBitAllignedNumber(buf: Buffer, byteOffset: number, bitOffset: * @param bitOffset Starting offset in bits: 0 = most significant bit, 7 is least significant bit * @return {number} decoded bit aligned number */ -export function isBitSet(buf: Buffer, byteOffset: number, bitOffset: number): boolean { +export function isBitSet(buf: Uint8Array, byteOffset: number, bitOffset: number): boolean { return getBitAllignedNumber(buf, byteOffset, bitOffset, 1) === 1; } diff --git a/lib/dsdiff/DsdiffParser.ts b/lib/dsdiff/DsdiffParser.ts index 552f216a6..42b0b0341 100644 --- a/lib/dsdiff/DsdiffParser.ts +++ b/lib/dsdiff/DsdiffParser.ts @@ -64,7 +64,7 @@ export class DsdiffParser extends BasicParser { break; case 'ID3': // Unofficial ID3 tag support - const id3_data = await this.tokenizer.readToken(new Token.BufferType(Number(header.chunkSize))); + const id3_data = await this.tokenizer.readToken(new Token.Uint8ArrayType(Number(header.chunkSize))); const rst = strtok3.fromBuffer(id3_data); await new ID3v2Parser().parse(this.metadata, rst, this.options); break; diff --git a/lib/flac/FlacParser.ts b/lib/flac/FlacParser.ts index da2575341..759ef7215 100644 --- a/lib/flac/FlacParser.ts +++ b/lib/flac/FlacParser.ts @@ -120,7 +120,7 @@ export class FlacParser extends AbstractID3Parser { * Ref: https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-640004.2.3 */ private async parseComment(dataLen: number): Promise { - const data = await this.tokenizer.readToken(new Token.BufferType(dataLen)); + const data = await this.tokenizer.readToken(new Token.Uint8ArrayType(dataLen)); const decoder = new VorbisDecoder(data, 0); decoder.readStringUtf8(); // vendor (skip) const commentListLength = decoder.readInt32(); @@ -183,7 +183,7 @@ interface IBlockStreamInfo { // A value of zero here means the number of total samples is unknown. totalSamples: number, // the MD5 hash of the file (see notes for usage... it's a littly tricky) - fileMD5: Buffer; + fileMD5: Uint8Array; } class Metadata { @@ -235,7 +235,7 @@ class Metadata { // A value of zero here means the number of total samples is unknown. totalSamples: util.getBitAllignedNumber(buf, off + 13, 4, 36), // the MD5 hash of the file (see notes for usage... it's a littly tricky) - fileMD5: new Token.BufferType(16).get(buf, off + 18) + fileMD5: new Token.Uint8ArrayType(16).get(buf, off + 18) }; } }; diff --git a/lib/id3v1/ID3v1Parser.ts b/lib/id3v1/ID3v1Parser.ts index 4eb021072..357a2cd6e 100644 --- a/lib/id3v1/ID3v1Parser.ts +++ b/lib/id3v1/ID3v1Parser.ts @@ -71,7 +71,7 @@ const Iid3v1Token: IGetToken = { * @param off Offset in buffer in bytes * @returns ID3v1.1 header if first 3 bytes equals 'TAG', otherwise null is returned */ - get: (buf, off): IId3v1Header => { + get: (buf: Buffer, off): IId3v1Header => { const header = new Id3v1StringType(3).get(buf, off); return header === "TAG" ? { header, diff --git a/lib/id3v2/ID3v2Token.ts b/lib/id3v2/ID3v2Token.ts index e26ceb747..c340aa5ed 100644 --- a/lib/id3v2/ID3v2Token.ts +++ b/lib/id3v2/ID3v2Token.ts @@ -47,7 +47,7 @@ export interface IExtendedHeader { * 4 * %0xxxxxxx */ export const UINT32SYNCSAFE = { - get: (buf: Buffer, off: number): number => { + get: (buf: Uint8Array, off: number): number => { return buf[off + 3] & 0x7f | ((buf[off + 2]) << 7) | ((buf[off + 1]) << 14) | ((buf[off]) << 21); }, @@ -86,7 +86,7 @@ export interface IID3v2header { export const ID3v2Header: IGetToken = { len: 10, - get: (buf, off): IID3v2header => { + get: (buf: Buffer, off): IID3v2header => { return { // ID3v2/file identifier "ID3" fileIdentifier: new Token.StringType(3, 'ascii').get(buf, off), diff --git a/lib/iff/index.ts b/lib/iff/index.ts index b932bb127..3048fe7d9 100644 --- a/lib/iff/index.ts +++ b/lib/iff/index.ts @@ -1,5 +1,6 @@ import {FourCcToken} from "../common/FourCC"; import { IGetToken } from "strtok3/lib/core"; +import * as Token from 'token-types'; /** * "EA IFF 85" Standard for Interchange Format Files @@ -44,7 +45,7 @@ export const Header: IGetToken = { // Chunk type ID chunkID: FourCcToken.get(buf, off), // Chunk size - chunkSize: buf.readUInt32BE(off + 4) + chunkSize: Number(BigInt(Token.UINT32_BE.get(buf, off + 4))) }; } }; diff --git a/lib/mp4/AtomToken.ts b/lib/mp4/AtomToken.ts index fdbc55c61..e438f362d 100644 --- a/lib/mp4/AtomToken.ts +++ b/lib/mp4/AtomToken.ts @@ -333,14 +333,14 @@ export class DataAtom implements IGetToken { public constructor(public len: number) { } - public get(buf: Buffer, off: number): IDataAtom { + public get(buf: Uint8Array, off: number): IDataAtom { return { type: { set: Token.UINT8.get(buf, off + 0), type: Token.UINT24_BE.get(buf, off + 1) }, locale: Token.UINT24_BE.get(buf, off + 4), - value: new Token.BufferType(this.len - 8).get(buf, off + 8) + value: Buffer.from(new Token.Uint8ArrayType(this.len - 8).get(buf, off + 8)) }; } } @@ -483,7 +483,7 @@ const stsdHeader: IGetToken = { export interface ISampleDescription { dataFormat: string; dataReferenceIndex: number; - description: Buffer; + description: Uint8Array; } export interface IAtomStsd { @@ -505,7 +505,7 @@ class SampleDescriptionTable implements IGetToken { return { dataFormat: FourCcToken.get(buf, off), dataReferenceIndex: Token.UINT16_BE.get(buf, off + 10), - description: new Token.BufferType(this.len - 12).get(buf, off + 12) + description: new Token.Uint8ArrayType(this.len - 12).get(buf, off + 12) }; } } diff --git a/lib/mpeg/MpegParser.ts b/lib/mpeg/MpegParser.ts index a3e79c82c..728d740b0 100644 --- a/lib/mpeg/MpegParser.ts +++ b/lib/mpeg/MpegParser.ts @@ -536,7 +536,7 @@ export class MpegParser extends AbstractID3Parser { private async skipSideInformation(): Promise { const sideinfo_length = this.audioFrameHeader.calculateSideInfoLength(); // side information - await this.tokenizer.readToken(new Token.BufferType(sideinfo_length)); + await this.tokenizer.readToken(new Token.Uint8ArrayType(sideinfo_length)); this.offset += sideinfo_length; await this.readXtraInfoHeader(); return; diff --git a/lib/musepack/sv7/StreamVersion7.ts b/lib/musepack/sv7/StreamVersion7.ts index b3858c8c1..8518fc3e3 100644 --- a/lib/musepack/sv7/StreamVersion7.ts +++ b/lib/musepack/sv7/StreamVersion7.ts @@ -44,7 +44,7 @@ export const Header: IGetToken = { const header = { // word 0 - signature: buf.toString("binary", off, off + 3), + signature: Buffer.from(buf).toString('latin1', 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), diff --git a/lib/ogg/Ogg.ts b/lib/ogg/Ogg.ts index d45ceab42..f0dc6fcdd 100644 --- a/lib/ogg/Ogg.ts +++ b/lib/ogg/Ogg.ts @@ -64,7 +64,7 @@ export interface IPageConsumer { * @param {IPageHeader} header Ogg page header * @param {Buffer} pageData Ogg page data */ - parsePage(header: IPageHeader, pageData: Buffer); + parsePage(header: IPageHeader, pageData: Uint8Array); /** * Calculate duration of provided header diff --git a/lib/ogg/OggParser.ts b/lib/ogg/OggParser.ts index 14a847996..9db402c8e 100644 --- a/lib/ogg/OggParser.ts +++ b/lib/ogg/OggParser.ts @@ -48,7 +48,7 @@ export class OggParser extends BasicParser { get: (buf, off): Ogg.IPageHeader => { return { capturePattern: FourCcToken.get(buf, off), - version: buf.readUInt8(off + 4), + version: Token.UINT8.get(buf, off + 4), headerType: { continued: util.getBit(buf, off + 5, 0), @@ -56,11 +56,11 @@ export class OggParser extends BasicParser { lastPage: util.getBit(buf, off + 5, 2) }, // packet_flag: buf.readUInt8(off + 5), - absoluteGranulePosition: buf.readIntLE(off + 6, 6), // cannot read 2 of 8 most significant bytes + absoluteGranulePosition: Number(Token.UINT64_LE.get(buf, off + 6)), streamSerialNumber: Token.UINT32_LE.get(buf, off + 14), pageSequenceNo: Token.UINT32_LE.get(buf, off + 18), pageChecksum: Token.UINT32_LE.get(buf, off + 22), - page_segments: buf.readUInt8(off + 26) + page_segments: Token.UINT8.get(buf, off + 26) }; } }; @@ -89,10 +89,10 @@ export class OggParser extends BasicParser { const segmentTable = await this.tokenizer.readToken(new SegmentTable(header)); debug('totalPageSize=%s', segmentTable.totalPageSize); - const pageData = await this.tokenizer.readToken(new Token.BufferType(segmentTable.totalPageSize)); + const pageData = await this.tokenizer.readToken(new Token.Uint8ArrayType(segmentTable.totalPageSize)); debug('firstPage=%s, lastPage=%s, continued=%s', header.headerType.firstPage, header.headerType.lastPage, header.headerType.continued); if (header.headerType.firstPage) { - const id = new Token.StringType(7, 'ascii').get(pageData, 0); + const id = new Token.StringType(7, 'ascii').get(Buffer.from(pageData), 0); switch (id) { case '\x01vorbis': // Ogg/Vorbis debug('Set page consumer to Ogg/Vorbis'); diff --git a/lib/ogg/speex/Speex.ts b/lib/ogg/speex/Speex.ts index 6ab5e9947..cdd3bc0b1 100644 --- a/lib/ogg/speex/Speex.ts +++ b/lib/ogg/speex/Speex.ts @@ -41,7 +41,7 @@ export const Header: IGetToken = { len: 80, - get: (buf, off) => { + get: (buf: Buffer, off) => { return { speex: new Token.StringType(8, 'ascii').get(buf, off + 0), diff --git a/lib/ogg/theora/Theora.ts b/lib/ogg/theora/Theora.ts index 3e80021dc..7b54d573e 100644 --- a/lib/ogg/theora/Theora.ts +++ b/lib/ogg/theora/Theora.ts @@ -31,7 +31,7 @@ export interface IIdentificationHeader { export const IdentificationHeader: IGetToken = { len: 42, - get: (buf, off): IIdentificationHeader => { + get: (buf: Buffer, off): IIdentificationHeader => { return { id: new Token.StringType(7, 'ascii').get(buf, off), vmaj: buf.readUInt8(off + 7), diff --git a/lib/ogg/vorbis/Vorbis.ts b/lib/ogg/vorbis/Vorbis.ts index 5fc36d80c..6332ec8ca 100644 --- a/lib/ogg/vorbis/Vorbis.ts +++ b/lib/ogg/vorbis/Vorbis.ts @@ -114,7 +114,7 @@ export interface ICommonHeader { export const CommonHeader: IGetToken = { len: 7, - get: (buf, off): ICommonHeader => { + get: (buf: Buffer, off): ICommonHeader => { return { packetType: buf.readUInt8(off), vorbis: new Token.StringType(6, 'ascii').get(buf, off + 1) @@ -142,14 +142,15 @@ export interface IFormatInfo { export const IdentificationHeader: IGetToken = { len: 23, - get: (buf, off): IFormatInfo => { + get: (uint8Array, off): IFormatInfo => { + const dataView = new DataView(uint8Array.buffer, uint8Array.byteOffset); return { - version: buf.readUInt32LE(off + 0), - channelMode: buf.readUInt8(off + 4), - sampleRate: buf.readUInt32LE(off + 5), - bitrateMax: buf.readUInt32LE(off + 9), - bitrateNominal: buf.readUInt32LE(off + 13), - bitrateMin: buf.readUInt32LE(off + 17) + version: dataView.getUint32(off + 0, true), + channelMode: dataView.getUint8(off + 4), + sampleRate: dataView.getUint32(off + 5, true), + bitrateMax: dataView.getUint32(off + 9, true), + bitrateNominal: dataView.getUint32(off + 13, true), + bitrateMin: dataView.getUint32(off + 17, true) }; } }; diff --git a/lib/ogg/vorbis/VorbisDecoder.ts b/lib/ogg/vorbis/VorbisDecoder.ts index d60f9f1c1..4aecd5cd7 100644 --- a/lib/ogg/vorbis/VorbisDecoder.ts +++ b/lib/ogg/vorbis/VorbisDecoder.ts @@ -2,7 +2,7 @@ import * as Token from 'token-types'; export class VorbisDecoder { - constructor(private readonly data: Buffer, private offset) { + constructor(private readonly data: Uint8Array, private offset) { } public readInt32(): number { @@ -13,7 +13,7 @@ export class VorbisDecoder { public readStringUtf8(): string { const len = this.readInt32(); - const value = this.data.toString('utf8', this.offset, this.offset + len); + const value = Buffer.from(this.data).toString('utf-8', this.offset, this.offset + len); this.offset += len; return value; } diff --git a/lib/riff/RiffChunk.ts b/lib/riff/RiffChunk.ts index 7f2c35a8a..cad44755b 100644 --- a/lib/riff/RiffChunk.ts +++ b/lib/riff/RiffChunk.ts @@ -9,12 +9,12 @@ export {IChunkHeader} from '../iff'; export const Header: IGetToken = { len: 8, - get: (buf, off): IChunkHeader => { + get: (buf: Buffer, off): IChunkHeader => { return { // Group-ID chunkID: buf.toString('binary', off, off + 4), // Size - chunkSize: buf.readUInt32LE(off + 4) + chunkSize: Token.UINT32_LE.get(buf, 4) }; } }; diff --git a/lib/wav/WaveParser.ts b/lib/wav/WaveParser.ts index 4ed323fb6..51070bd56 100644 --- a/lib/wav/WaveParser.ts +++ b/lib/wav/WaveParser.ts @@ -94,7 +94,7 @@ export class WaveParser extends BasicParser { case 'id3 ': // The way Picard, FooBar currently stores, ID3 meta-data case 'ID3 ': // The way Mp3Tags stores ID3 meta-data - const id3_data = await this.tokenizer.readToken(new Token.BufferType(header.chunkSize)); + const id3_data = await this.tokenizer.readToken(new Token.Uint8ArrayType(header.chunkSize)); const rst = strtok3.fromBuffer(id3_data); await new ID3v2Parser().parse(this.metadata, rst, this.options); break; diff --git a/lib/wavpack/WavPackToken.ts b/lib/wavpack/WavPackToken.ts index 360e6d983..741237ec9 100644 --- a/lib/wavpack/WavPackToken.ts +++ b/lib/wavpack/WavPackToken.ts @@ -42,7 +42,7 @@ export interface IBlockHeader { // false = PCM audio; true = DSD audio (ver 5.0+) } // crc for actual decoded data - crc: Buffer + crc: Uint8Array } export interface IMetadataId { @@ -109,7 +109,7 @@ export class WavPack { isDSD: WavPack.isBitSet(flags, 31) }, // crc for actual decoded data - crc: new Token.BufferType(4).get(buf, off + 28) + crc: new Token.Uint8ArrayType(4).get(buf, off + 28) }; if (res.flags.isDSD) { diff --git a/package.json b/package.json index 47d2df69e..af1415cb0 100644 --- a/package.json +++ b/package.json @@ -87,10 +87,11 @@ "debug": "^4.3.2", "file-type": "16.5.2", "media-typer": "^1.1.0", - "strtok3": "6.1.3", - "token-types": "3.0.0" + "strtok3": "^6.2.2", + "token-types": "^4.1.0" }, "devDependencies": { + "@tokenizer/token": "^0.3.0", "@types/chai": "^4.2.21", "@types/debug": "^4.1.6", "@types/file-type": "^10.9.1", diff --git a/test/test-file-asf.ts b/test/test-file-asf.ts index 5cb23407b..a6416fa06 100644 --- a/test/test-file-asf.ts +++ b/test/test-file-asf.ts @@ -1,15 +1,15 @@ import { assert } from 'chai'; import * as mm from '../lib'; import * as path from 'path'; -import GUID from "../lib/asf/GUID"; -import { AsfUtil } from "../lib/asf/AsfUtil"; -import { DataType } from "../lib/asf/AsfObject"; +import GUID from '../lib/asf/GUID'; +import { AsfUtil } from '../lib/asf/AsfUtil'; +import { DataType } from '../lib/asf/AsfObject'; import { Parsers } from './metadata-parsers'; -describe("Parse ASF", () => { +describe('Parse ASF', () => { - describe("GUID", () => { - it("should construct GUID from string", () => { + describe('GUID', () => { + it('should construct GUID from string', () => { const Header_GUID = Buffer.from([ 0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, @@ -18,67 +18,73 @@ describe("Parse ASF", () => { assert.deepEqual(GUID.HeaderObject.toBin(), Header_GUID); }); + + it('should construct GUID from string', () => { + + const guid_data = Buffer.from([48, 38, 178, 117, 142, 102, 207, 17, 166, 217, 0, 170, 0, 98, 206, 108]); + assert.deepEqual(GUID.fromBin(guid_data).str, '75B22630-668E-11CF-A6D9-00AA0062CE6C'); + }); }); /** * Trying Buffer.readUIntLE(0, 8) * Where 8 is 2 bytes longer then maximum allowed of 6 */ - it("should be able to roughly decode a 64-bit QWord", () => { + it('should be able to roughly decode a 64-bit QWord', () => { const tests: { raw: string, expected: number, description: string }[] = [ { - raw: "\xFF\x00\x00\x00\x00\x00\x00\x00", + raw: '\xFF\x00\x00\x00\x00\x00\x00\x00', expected: 0xFF, - description: "8-bit" + description: '8-bit' }, { - raw: "\xFF\xFF\x00\x00\x00\x00\x00\x00", + raw: '\xFF\xFF\x00\x00\x00\x00\x00\x00', expected: 0xFFFF, - description: "16-bit" + description: '16-bit' }, { - raw: "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", + raw: '\xFF\xFF\xFF\xFF\x00\x00\x00\x00', expected: 0xFFFFFFFF, - description: "32-bit" + description: '32-bit' }, { - raw: "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", + raw: '\xFF\xFF\xFF\xFF\xFF\x00\x00\x00', expected: 0xFFFFFFFFFF, - description: "40-bit" + description: '40-bit' }, { - raw: "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", + raw: '\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00', expected: 0xFFFFFFFFFFFF, - description: "48-bit" + description: '48-bit' }, { - raw: "\xFF\xFF\xFF\xFF\xFF\xFF\x0F\x00", + raw: '\xFF\xFF\xFF\xFF\xFF\xFF\x0F\x00', expected: 0xFFFFFFFFFFFFF, - description: "52-bit" + description: '52-bit' } ]; tests.forEach(test => { - const buf = Buffer.from(test.raw, "binary"); + const buf = Buffer.from(test.raw, 'binary'); assert.strictEqual(Number(AsfUtil.getParserForAttr(DataType.QWord)(buf)), test.expected, test.description); }); }); - describe("parse", () => { + describe('parse', () => { const asfFilePath = path.join(__dirname, 'samples', 'asf'); function checkFormat(format) { assert.strictEqual(format.container, 'ASF/audio', 'format.container'); assert.strictEqual(format.codec, 'Windows Media Audio 9.1', 'format.codec'); - assert.approximately(format.duration, 243.306, 1 / 10000, "format.duration"); + assert.approximately(format.duration, 243.306, 1 / 10000, 'format.duration'); assert.strictEqual(format.bitrate, 192639, 'format.bitrate'); } function checkCommon(common) { - assert.strictEqual(common.title, "Don't Bring Me Down", 'common.title'); + assert.strictEqual(common.title, 'Don\'t Bring Me Down', 'common.title'); assert.deepEqual(common.artist, 'Electric Light Orchestra', 'common.artist'); assert.deepEqual(common.albumartist, 'Electric Light Orchestra', 'common.albumartist'); assert.strictEqual(common.album, 'Discovery', 'common.album'); @@ -95,7 +101,7 @@ describe("Parse ASF", () => { assert.deepEqual(native.REPLAYGAIN_TRACK_GAIN, ['-4.7 dB'], 'native: REPLAYGAIN_TRACK_GAIN'); } - describe("should decode an ASF audio file (.wma)", () => { + describe('should decode an ASF audio file (.wma)', () => { Parsers.forEach(parser => { it(parser.description, async () => { @@ -111,7 +117,7 @@ describe("Parse ASF", () => { }); - describe("should decode picture from", () => { + describe('should decode picture from', () => { Parsers.forEach(parser => { it(parser.description, async () => { @@ -129,7 +135,7 @@ describe("Parse ASF", () => { /** * Related issue: https://github.com/Borewit/music-metadata/issues/68 */ - it("should be able to parse truncated .wma file", async () => { + it('should be able to parse truncated .wma file', async () => { const filePath = path.join(asfFilePath, '13 Thirty Dirty Birds.wma'); @@ -143,11 +149,11 @@ describe("Parse ASF", () => { const asf = mm.orderTags(native.asf); // ToDo: Contains some WM/... tags which could be parsed / mapped better - assert.strictEqual(common.title, "Thirty Dirty Birds", "metadata.common.title"); - assert.strictEqual(common.artist, "The Red Hot Chili Peppers", "metadata.common.artist"); - assert.strictEqual(common.date, "2003", "metadata.common.date"); - assert.deepEqual(common.label, ["Capitol"], "metadata.common.label"); - assert.strictEqual(common.track.no, 13, "metadata.common.track.no"); + assert.strictEqual(common.title, 'Thirty Dirty Birds', 'metadata.common.title'); + assert.strictEqual(common.artist, 'The Red Hot Chili Peppers', 'metadata.common.artist'); + assert.strictEqual(common.date, '2003', 'metadata.common.date'); + assert.deepEqual(common.label, ['Capitol'], 'metadata.common.label'); + assert.strictEqual(common.track.no, 13, 'metadata.common.track.no'); assert.exists(asf); }); diff --git a/yarn.lock b/yarn.lock index f57cf45ee..8acc59546 100644 --- a/yarn.lock +++ b/yarn.lock @@ -279,6 +279,11 @@ resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.1.1.tgz#f0d92c12f87079ddfd1b29f614758b9696bc29e3" integrity sha512-XO6INPbZCxdprl+9qa/AAbFFOMzzwqYxpjPgLICrMD6C2FCw6qfJOPcBk6JqqPLSaZ/Qx87qn4rpPmPMwaAK6w== +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + "@tsconfig/node10@^1.0.7": version "1.0.8" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" @@ -333,7 +338,12 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.3.tgz#bbeb55fbc73f28ea6de601fbfa4613f58d785323" integrity sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw== -"@types/node@*", "@types/node@^16.4.0": +"@types/node@*": + version "16.3.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.3.1.tgz#24691fa2b0c3ec8c0d34bfcfd495edac5593ebb4" + integrity sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA== + +"@types/node@^16.4.0": version "16.4.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.0.tgz#2c219eaa3b8d1e4d04f4dd6e40bc68c7467d5272" integrity sha512-HrJuE7Mlqcjj+00JqMWpZ3tY8w7EUd+S0U3L1+PQSWiXZbOgyQDvi+ogoUxaHApPJq5diKxYBQwA3iIlNcPqOg== @@ -1239,7 +1249,16 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-type@*, file-type@16.5.2: +file-type@*: + version "16.5.1" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.1.tgz#dd697dc5c3a2f4db63af746f38a6322e5e7bc6a5" + integrity sha512-Pi1G43smrCy82Q3be3sfKaeS5uHdfj905dP88YqhroG6TYbVY2ljTdDXeXqa6Cn5nOk6znOjWM2uZptA8vH/qQ== + dependencies: + readable-web-to-node-stream "^3.0.0" + strtok3 "^6.0.3" + token-types "^2.0.0" + +file-type@16.5.2: version "16.5.2" resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.2.tgz#e6626f7a253af2ecf499f31995f0e849226825a8" integrity sha512-lnHRZj2USLF3v4C5ZY7/vQQeoTVA1YV9TtD6UUCr9z5Cd0uyutqxPBJxkXzM6lufPNuSfefq/yFmnSPz0C3wNw== @@ -2534,6 +2553,11 @@ peek-readable@^3.1.4: resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-3.1.4.tgz#f5c3b41a4eeb63a1322c4131f0b5bac7105b892e" integrity sha512-DX7ec7frSMtCWw+zMd27f66hcxIz/w9LQTY2RflB4WNHCVPAye1pJiP2t3gvaaOhu7IOhtPbHw8MemMj+F5lrg== +peek-readable@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.0.0.tgz#b024ef391c86136eba0ae9df3ff4f966a09e9a7e" + integrity sha512-kLbU4cz6h86poGVBKgAVMpFmD47nX04fPPQNKnv9fuj+IJZYkEBjsYAVu5nDbZWx0ZsWwWlMzeG90zQa5KLBaA== + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -3258,6 +3282,22 @@ strtok3@6.1.3: "@tokenizer/token" "^0.1.1" peek-readable "^3.1.4" +strtok3@^6.0.3: + version "6.1.2" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.1.2.tgz#4422aff1a50cf61652a03a9888f4a71386aae4b7" + integrity sha512-ECqYgTe/FU1r2fSgXaCywfhoveNNxDWcGSaJesD7OvlrQLIwSck8mZT6xxYdnI4q0l8SwrrExx/01chzUM4Dzw== + dependencies: + "@tokenizer/token" "^0.1.1" + "@types/debug" "^4.1.6" + peek-readable "^3.1.4" + +strtok3@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.2.2.tgz#aad1da5fc28bf10d603c367c2a7f9f47a6c1d2d9" + integrity sha512-iUzLl3UhF2RfqQah80JngnfltQFLEidGyTX8+hHFMQFjzUj3UpIpOx824FtFmRI9bwyywReENpdHGDkFJwJlGQ== + dependencies: + peek-readable "^4.0.0" + supports-color@8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" @@ -3332,10 +3372,10 @@ to-vfile@^6.0.0: is-buffer "^2.0.0" vfile "^4.0.0" -token-types@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/token-types/-/token-types-3.0.0.tgz#982fb4e705103bc647fd281b06de213ea06ce65a" - integrity sha512-1cV7R6TRKfCG1++se5xGy9fUpD+L1u/7XgmViGA1Y5bubHt6W4w1r1j0uOk+5ngM6yhssRJ+qR+IaviVgAizJA== +token-types@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-2.1.1.tgz#bd585d64902aaf720b8979d257b4b850b4d45c45" + integrity sha512-wnQcqlreS6VjthyHO3Y/kpK/emflxDBNhlNUPfh7wE39KnuDdOituXomIbyI79vBtF0Ninpkh72mcuRHo+RG3Q== dependencies: "@tokenizer/token" "^0.1.1" ieee754 "^1.2.1" @@ -3348,6 +3388,13 @@ token-types@^3.0.0: "@tokenizer/token" "^0.1.1" ieee754 "^1.2.1" +token-types@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.1.0.tgz#63398cb6fbbf8845538cabb8ecb47bdeca5956de" + integrity sha512-2JV21LhBx3WsTveWcXp20SDo0/fQ2TK2RFcFBIRDvkOIy6+E79n+rqMuvolqyuWPgYazCrHXWpE0OxRj43nb9Q== + dependencies: + ieee754 "^1.2.1" + tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"