Files
konoebml/src/factory.ts
2025-03-18 02:46:18 +08:00

181 lines
5.1 KiB
TypeScript

import { InconsistentWellKnownEbmlTagTypeError } from './errors';
import {
type EbmlBlockTagIdType,
type EbmlDataTagIdType,
EbmlElementType,
type EbmlMasterTagIdType,
type EbmlSimpleBlockTagIdType,
EbmlTagIdEnum,
isEbmlBinaryDataTagId,
isEbmlBlockTagId,
isEbmlDateDataTagId,
isEbmlFloatDataTagId,
isEbmlIntDataTagId,
isEbmlMasterTagId,
isEbmlSimpleBlockTagId,
isEbmlStringDataTagId,
isEbmlUintDataTagId,
isEbmlUtf8DataTagId,
} from './models/enums';
import {
type CreateEbmlBlockTagOptions,
EbmlBlockTag,
} from './models/tag-block';
import { type CreateEbmlDataTagOptions, EbmlDataTag } from './models/tag-data';
import {
type CreateEbmlMasterTagOptions,
EbmlMasterTag,
} from './models/tag-master';
import {
type CreateEbmlSimpleBlockTagOptions,
EbmlSimpleBlockTag,
} from './models/tag-simple-block';
import type { CreateEbmlTagOptions, EbmlTagTrait } from './models/tag-trait';
export function createEbmlTag(
id: EbmlMasterTagIdType,
options: Omit<CreateEbmlMasterTagOptions, 'id'>
): EbmlMasterTag;
export function createEbmlTag(
id: EbmlDataTagIdType,
options: Omit<CreateEbmlDataTagOptions, 'id'>
): EbmlDataTag;
export function createEbmlTag(
id: EbmlBlockTagIdType,
options: Omit<CreateEbmlBlockTagOptions, 'id'>
): EbmlBlockTag;
export function createEbmlTag(
id: EbmlSimpleBlockTagIdType,
options: Omit<CreateEbmlSimpleBlockTagOptions, 'id'>
): EbmlSimpleBlockTag;
export function createEbmlTag(
id: CreateEbmlTagOptions['id'],
options: Omit<CreateEbmlTagOptions, 'id'>
): EbmlTagTrait;
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
export function createEbmlTag(arg1: unknown, arg2: unknown): EbmlTagTrait {
const id = arg1 as EbmlTagIdEnum;
const options = arg2 as Omit<CreateEbmlTagOptions, 'id'>;
let type: EbmlElementType | undefined = options.type;
if (EbmlTagIdEnum[id] !== undefined) {
let foundType: EbmlElementType | undefined;
if (isEbmlBlockTagId(id)) {
return new EbmlBlockTag({ ...options, id });
}
if (isEbmlSimpleBlockTagId(id)) {
return new EbmlSimpleBlockTag({ ...options });
}
if (isEbmlMasterTagId(id)) {
foundType = EbmlElementType.Master;
} else if (isEbmlUintDataTagId(id)) {
foundType = EbmlElementType.UnsignedInt;
} else if (isEbmlIntDataTagId(id)) {
foundType = EbmlElementType.Integer;
} else if (isEbmlFloatDataTagId(id)) {
foundType = EbmlElementType.Float;
} else if (isEbmlStringDataTagId(id)) {
foundType = EbmlElementType.Ascii;
} else if (isEbmlUtf8DataTagId(id)) {
foundType = EbmlElementType.UTF8;
} else if (isEbmlDateDataTagId(id)) {
foundType = EbmlElementType.Date;
} else if (isEbmlBinaryDataTagId(id)) {
foundType = EbmlElementType.Binary;
}
if (type === undefined) {
type = foundType;
}
if (type !== foundType) {
throw new InconsistentWellKnownEbmlTagTypeError(id, type!);
}
}
if (type === EbmlElementType.Master) {
return new EbmlMasterTag({
...options,
id: id as EbmlMasterTagIdType,
});
}
return new EbmlDataTag({
...options,
id,
type,
});
}
export type EncodeUselessCreateOptionsType =
| 'contentLength'
| 'headerLength'
| 'startOffset';
export function createEbmlTagForManuallyBuild(
id: EbmlMasterTagIdType,
options: Omit<
CreateEbmlMasterTagOptions,
'id' | EncodeUselessCreateOptionsType
> &
Partial<Pick<CreateEbmlMasterTagOptions, EncodeUselessCreateOptionsType>>
): EbmlMasterTag;
export function createEbmlTagForManuallyBuild(
id: EbmlDataTagIdType,
options: Omit<
CreateEbmlDataTagOptions,
'id' | EncodeUselessCreateOptionsType
> &
Partial<Pick<CreateEbmlMasterTagOptions, EncodeUselessCreateOptionsType>>
): EbmlDataTag;
export function createEbmlTagForManuallyBuild(
id: EbmlBlockTagIdType,
options: Omit<
CreateEbmlBlockTagOptions,
'id' | EncodeUselessCreateOptionsType
> &
Partial<Pick<CreateEbmlMasterTagOptions, EncodeUselessCreateOptionsType>>
): EbmlBlockTag;
export function createEbmlTagForManuallyBuild(
id: EbmlSimpleBlockTagIdType,
options: Omit<
CreateEbmlSimpleBlockTagOptions,
'id' | EncodeUselessCreateOptionsType
> &
Partial<Pick<CreateEbmlMasterTagOptions, EncodeUselessCreateOptionsType>>
): EbmlSimpleBlockTag;
export function createEbmlTagForManuallyBuild(
id: CreateEbmlTagOptions['id'],
options: Omit<CreateEbmlTagOptions, 'id' | EncodeUselessCreateOptionsType> &
Partial<Pick<CreateEbmlMasterTagOptions, EncodeUselessCreateOptionsType>>
): EbmlTagTrait;
export function createEbmlTagForManuallyBuild(
arg1: unknown,
arg2: unknown
): EbmlTagTrait {
const id = arg1 as CreateEbmlTagOptions['id'];
const options = arg2 as Omit<
CreateEbmlTagOptions,
'id' | EncodeUselessCreateOptionsType
> &
Partial<Pick<CreateEbmlMasterTagOptions, EncodeUselessCreateOptionsType>>;
return createEbmlTag(
id,
Object.assign(
{
contentLength: Number.NaN,
headerLength: Number.NaN,
startOffset: Number.NaN,
},
options
) as Omit<CreateEbmlTagOptions, 'id'>
);
}