import PDFObject from 'src/core/objects/PDFObject' ; import CharCodes from 'src/core/syntax/CharCodes' ; import { copyStringIntoBuffer , toHexStringOfMinLength , utf16Decode , utf16Encode , pdfDocEncodingDecode , parseDate , hasUtf16BOM , } from 'src/utils' ; import { InvalidPDFDateStringError } from 'src/core/errors' ; class PDFHexString extends PDFObject { static of = ( value ) => new PDFHexString ( value ) ; static fromText = ( value ) => { const encoded = utf16Encode ( value ) ; let hex = '' ; for ( let idx = 0 , len = encoded . length ; idx < len ; idx ++ ) { hex += toHexStringOfMinLength ( encoded [ idx ] , 4 ) ; } return new PDFHexString ( hex ) ; } ; private readonly value : string ; constructor ( value ) { super ( ) ; this . value = value ; } asBytes ( ) { const hex = this . value + ( this . value . length % 2 === 1 ? '0' : '' ) ; const hexLength = hex . length ; const bytes = new Uint8Array ( hex . length / 2 ) ; let hexOffset = 0 ; let bytesOffset = 0 ; while ( hexOffset < hexLength ) { const byte = parseInt ( hex . substring ( hexOffset , hexOffset + 2 ) , 16 ) ; bytes [ bytesOffset ] = byte ; hexOffset += 2 ; bytesOffset += 1 ; } return bytes ; } decodeText ( ) { const bytes = this . asBytes ( ) ; if ( hasUtf16BOM ( bytes ) ) return utf16Decode ( bytes ) ; return pdfDocEncodingDecode ( bytes ) ; } decodeDate ( ) { const text = this . decodeText ( ) ; const date = parseDate ( text ) ; if ( ! date ) throw new InvalidPDFDateStringError ( text ) ; return date ; } asString ( ) { return this . value ; } clone ( ) { return PDFHexString . of ( this . value ) ; } toString ( ) { return `<${ this . value }>` ; } sizeInBytes ( ) { return this . value . length + 2 ; } copyBytesInto ( buffer , offset ) { buffer [ offset ++ ] = CharCodes . LessThan ; offset += copyStringIntoBuffer ( this . value , buffer , offset ) ; buffer [ offset ++ ] = CharCodes . GreaterThan ; return this . value . length + 2 ; } } export default PDFHexString ;