import { PrivateConstructorError } from 'src/core/errors' ; import PDFObject from 'src/core/objects/PDFObject' ; import CharCodes from 'src/core/syntax/CharCodes' ; import { IsIrregular } from 'src/core/syntax/Irregular' ; import { charFromHexCode , copyStringIntoBuffer , toCharCode , toHexString , } from 'src/utils' ; const decodeName = ( name ) => name . replace ( /#([\dABCDEF]{2})/g , ( _ , hex ) => charFromHexCode ( hex ) ) ; const isRegularChar = ( charCode ) => charCode >= CharCodes . ExclamationPoint && charCode <= CharCodes . Tilde && ! IsIrregular [ charCode ] ; const ENFORCER = { } ; const pool = new Map < string , PDFName > ( ) ; class PDFName extends PDFObject { static of = ( name ) : PDFName => { const decodedValue = decodeName ( name ) ; let instance = pool . get ( decodedValue ) ; if ( ! instance ) { instance = new PDFName ( ENFORCER , decodedValue ) ; pool . set ( decodedValue , instance ) ; } return instance ; } ; static readonly Length = PDFName . of ( 'Length' ) ; static readonly FlateDecode = PDFName . of ( 'FlateDecode' ) ; static readonly Resources = PDFName . of ( 'Resources' ) ; static readonly Font = PDFName . of ( 'Font' ) ; static readonly XObject = PDFName . of ( 'XObject' ) ; static readonly ExtGState = PDFName . of ( 'ExtGState' ) ; static readonly Contents = PDFName . of ( 'Contents' ) ; static readonly Type = PDFName . of ( 'Type' ) ; static readonly Parent = PDFName . of ( 'Parent' ) ; static readonly MediaBox = PDFName . of ( 'MediaBox' ) ; static readonly Page = PDFName . of ( 'Page' ) ; static readonly Annots = PDFName . of ( 'Annots' ) ; static readonly TrimBox = PDFName . of ( 'TrimBox' ) ; static readonly ArtBox = PDFName . of ( 'ArtBox' ) ; static readonly BleedBox = PDFName . of ( 'BleedBox' ) ; static readonly CropBox = PDFName . of ( 'CropBox' ) ; static readonly Rotate = PDFName . of ( 'Rotate' ) ; static readonly Title = PDFName . of ( 'Title' ) ; static readonly Author = PDFName . of ( 'Author' ) ; static readonly Subject = PDFName . of ( 'Subject' ) ; static readonly Creator = PDFName . of ( 'Creator' ) ; static readonly Keywords = PDFName . of ( 'Keywords' ) ; static readonly Producer = PDFName . of ( 'Producer' ) ; static readonly CreationDate = PDFName . of ( 'CreationDate' ) ; static readonly ModDate = PDFName . of ( 'ModDate' ) ; private readonly encodedName : string ; private constructor ( enforcer , name ) { if ( enforcer !== ENFORCER ) throw new PrivateConstructorError ( 'PDFName' ) ; super ( ) ; let encodedName = '/' ; for ( let idx = 0 , len = name . length ; idx < len ; idx ++ ) { const character = name [ idx ] ; const code = toCharCode ( character ) ; encodedName += isRegularChar ( code ) ? character : `#${ toHexString ( code ) }` ; } this . encodedName = encodedName ; } asBytes ( ) { const bytes = [ ] ; let hex = '' ; let escaped = false ; const pushByte = ( byte ? ) => { if ( byte !== undefined ) bytes . push ( byte ) ; escaped = false ; } ; for ( let idx = 1 , len = this . encodedName . length ; idx < len ; idx ++ ) { const char = this . encodedName [ idx ] ; const byte = toCharCode ( char ) ; const nextChar = this . encodedName [ idx + 1 ] ; if ( ! escaped ) { if ( byte === CharCodes . Hash ) escaped = true ; else pushByte ( byte ) ; } else { if ( ( byte >= CharCodes . Zero && byte <= CharCodes . Nine ) || ( byte >= CharCodes . a && byte <= CharCodes . f ) || ( byte >= CharCodes . A && byte <= CharCodes . F ) ) { hex += char ; if ( hex . length === 2 || ! ( ( nextChar >= '0' && nextChar <= '9' ) || ( nextChar >= 'a' && nextChar <= 'f' ) || ( nextChar >= 'A' && nextChar <= 'F' ) ) ) { pushByte ( parseInt ( hex , 16 ) ) ; hex = '' ; } } else { pushByte ( byte ) ; } } } return new Uint8Array ( bytes ) ; } decodeText ( ) { const bytes = this . asBytes ( ) ; return String . fromCharCode ( ... Array . from ( bytes ) ) ; } asString ( ) { return this . encodedName ; } deprecated value ( ) { return this . encodedName ; } clone ( ) { return this ; } toString ( ) { return this . encodedName ; } sizeInBytes ( ) { return this . encodedName . length ; } copyBytesInto ( buffer , offset ) { offset += copyStringIntoBuffer ( this . encodedName , buffer , offset ) ; return this . encodedName . length ; } } export default PDFName ;