@@ -1582,372 +1582,3 @@ const decodeSimpleOrFloatAt = (data: Uint8Array, offset: number): DecodeAtResult
15821582 }
15831583 throw new CBORError ( { message : `Unsupported simple/float encoding: ${ additionalInfo } ` } )
15841584}
1585-
1586- const decodeUintSync = ( data : Uint8Array ) : CBOR => {
1587- const firstByte = data [ 0 ]
1588- const additionalInfo = firstByte & 0x1f
1589- if ( additionalInfo < 24 ) {
1590- return BigInt ( additionalInfo )
1591- } else if ( additionalInfo === 24 ) {
1592- if ( data . length < 2 ) throw new CBORError ( { message : "Insufficient data for 1-byte unsigned integer" } )
1593- return BigInt ( data [ 1 ] )
1594- } else if ( additionalInfo === 25 ) {
1595- if ( data . length < 3 ) throw new CBORError ( { message : "Insufficient data for 2-byte unsigned integer" } )
1596- return BigInt ( data [ 1 ] ) * 256n + BigInt ( data [ 2 ] )
1597- } else if ( additionalInfo === 26 ) {
1598- if ( data . length < 5 ) throw new CBORError ( { message : "Insufficient data for 4-byte unsigned integer" } )
1599- return BigInt ( data [ 1 ] ) * 16777216n + BigInt ( data [ 2 ] ) * 65536n + BigInt ( data [ 3 ] ) * 256n + BigInt ( data [ 4 ] )
1600- } else if ( additionalInfo === 27 ) {
1601- if ( data . length < 9 ) throw new CBORError ( { message : "Insufficient data for 8-byte unsigned integer" } )
1602- let result = 0n
1603- for ( let i = 1 ; i <= 8 ; i ++ ) result = result * 256n + BigInt ( data [ i ] )
1604- return result
1605- } else {
1606- throw new CBORError ( { message : `Unsupported additional info for unsigned integer: ${ additionalInfo } ` } )
1607- }
1608- }
1609-
1610- const decodeNintSync = ( data : Uint8Array ) : CBOR => {
1611- const firstByte = data [ 0 ]
1612- const additionalInfo = firstByte & 0x1f
1613- if ( additionalInfo < 24 ) {
1614- return - 1n - BigInt ( additionalInfo )
1615- } else if ( additionalInfo === 24 ) {
1616- if ( data . length < 2 ) throw new CBORError ( { message : "Insufficient data for 1-byte negative integer" } )
1617- return - 1n - BigInt ( data [ 1 ] )
1618- } else if ( additionalInfo === 25 ) {
1619- if ( data . length < 3 ) throw new CBORError ( { message : "Insufficient data for 2-byte negative integer" } )
1620- return - 1n - ( BigInt ( data [ 1 ] ) * 256n + BigInt ( data [ 2 ] ) )
1621- } else if ( additionalInfo === 26 ) {
1622- if ( data . length < 5 ) throw new CBORError ( { message : "Insufficient data for 4-byte negative integer" } )
1623- return - 1n - ( BigInt ( data [ 1 ] ) * 16777216n + BigInt ( data [ 2 ] ) * 65536n + BigInt ( data [ 3 ] ) * 256n + BigInt ( data [ 4 ] ) )
1624- } else if ( additionalInfo === 27 ) {
1625- if ( data . length < 9 ) throw new CBORError ( { message : "Insufficient data for 8-byte negative integer" } )
1626- let result = 0n
1627- for ( let i = 1 ; i <= 8 ; i ++ ) result = result * 256n + BigInt ( data [ i ] )
1628- return - 1n - result
1629- } else {
1630- throw new CBORError ( { message : `Unsupported additional info for negative integer: ${ additionalInfo } ` } )
1631- }
1632- }
1633-
1634- const decodeBytesWithLengthSync = ( data : Uint8Array ) : { item : CBOR ; bytesConsumed : number } => {
1635- const firstByte = data [ 0 ]
1636- const additionalInfo = firstByte & 0x1f
1637- if ( additionalInfo === CBOR_ADDITIONAL_INFO . INDEFINITE ) {
1638- let offset = 1
1639- const chunks : Array < Uint8Array > = [ ]
1640- let foundBreak = false
1641- while ( offset < data . length ) {
1642- if ( data [ offset ] === 0xff ) {
1643- offset ++
1644- foundBreak = true
1645- break
1646- }
1647- const chunkFirstByte = data [ offset ]
1648- const chunkMajorType = ( chunkFirstByte >> 5 ) & 0x07
1649- if ( chunkMajorType !== CBOR_MAJOR_TYPE . BYTE_STRING ) {
1650- throw new CBORError ( { message : `Invalid chunk in indefinite byte string: major type ${ chunkMajorType } ` } )
1651- }
1652- const { bytesRead, length : chunkLength } = decodeLengthSync ( data , offset )
1653- offset += bytesRead
1654- if ( data . length < offset + chunkLength )
1655- throw new CBORError ( { message : "Insufficient data for byte string chunk" } )
1656- const chunk = data . slice ( offset , offset + chunkLength )
1657- chunks . push ( chunk )
1658- offset += chunkLength
1659- }
1660- if ( ! foundBreak ) throw new CBORError ( { message : "Missing break in indefinite-length byte string" } )
1661- const totalLength = chunks . reduce ( ( sum , chunk ) => sum + chunk . length , 0 )
1662- const bytes = new Uint8Array ( totalLength )
1663- let pos = 0
1664- for ( const chunk of chunks ) {
1665- bytes . set ( chunk , pos )
1666- pos += chunk . length
1667- }
1668- return { item : bytes , bytesConsumed : offset }
1669- } else {
1670- const { bytesRead, length } = decodeLengthSync ( data , 0 )
1671- if ( data . length < bytesRead + length ) throw new CBORError ( { message : "Insufficient data for byte string" } )
1672- const bytes = data . slice ( bytesRead , bytesRead + length )
1673- return { item : bytes , bytesConsumed : bytesRead + length }
1674- }
1675- }
1676-
1677- const decodeTextWithLengthSync = ( data : Uint8Array ) : { item : CBOR ; bytesConsumed : number } => {
1678- const firstByte = data [ 0 ]
1679- const additionalInfo = firstByte & 0x1f
1680- if ( additionalInfo === CBOR_ADDITIONAL_INFO . INDEFINITE ) {
1681- let offset = 1
1682- const parts : Array < string > = [ ]
1683- let foundBreak = false
1684- while ( offset < data . length ) {
1685- if ( data [ offset ] === 0xff ) {
1686- offset ++
1687- foundBreak = true
1688- break
1689- }
1690- const chunkFirstByte = data [ offset ]
1691- const chunkMajorType = ( chunkFirstByte >> 5 ) & 0x07
1692- if ( chunkMajorType !== CBOR_MAJOR_TYPE . TEXT_STRING ) {
1693- throw new CBORError ( { message : `Invalid chunk in indefinite text string: major type ${ chunkMajorType } ` } )
1694- }
1695- const { bytesRead, length : chunkLength } = decodeLengthSync ( data , offset )
1696- offset += bytesRead
1697- if ( data . length < offset + chunkLength )
1698- throw new CBORError ( { message : "Insufficient data for text string chunk" } )
1699- const chunkBytes = data . slice ( offset , offset + chunkLength )
1700- const chunkText = TEXT_DECODER . decode ( chunkBytes )
1701- parts . push ( chunkText )
1702- offset += chunkLength
1703- }
1704- if ( ! foundBreak ) throw new CBORError ( { message : "Missing break in indefinite-length text string" } )
1705- return { item : parts . join ( "" ) , bytesConsumed : offset }
1706- } else {
1707- const { bytesRead, length } = decodeLengthSync ( data , 0 )
1708- if ( data . length < bytesRead + length ) throw new CBORError ( { message : "Insufficient data for text string" } )
1709- const textBytes = data . slice ( bytesRead , bytesRead + length )
1710- const text = TEXT_DECODER . decode ( textBytes )
1711- return { item : text , bytesConsumed : bytesRead + length }
1712- }
1713- }
1714-
1715- // Decode an item and return both the item and bytes consumed (sync)
1716- const decodeItemWithLengthSync = ( data : Uint8Array , options : CodecOptions ) : { item : CBOR ; bytesConsumed : number } => {
1717- const firstByte = data [ 0 ]
1718- const majorType = ( firstByte >> 5 ) & 0x07
1719- let item : CBOR
1720- let bytesConsumed : number
1721- switch ( majorType ) {
1722- case CBOR_MAJOR_TYPE . UNSIGNED_INTEGER : {
1723- item = decodeUintSync ( data )
1724- const additionalInfo = firstByte & 0x1f
1725- bytesConsumed =
1726- additionalInfo < 24 ? 1 : additionalInfo === 24 ? 2 : additionalInfo === 25 ? 3 : additionalInfo === 26 ? 5 : 9
1727- break
1728- }
1729- case CBOR_MAJOR_TYPE . NEGATIVE_INTEGER : {
1730- item = decodeNintSync ( data )
1731- const additionalInfo = firstByte & 0x1f
1732- bytesConsumed =
1733- additionalInfo < 24 ? 1 : additionalInfo === 24 ? 2 : additionalInfo === 25 ? 3 : additionalInfo === 26 ? 5 : 9
1734- break
1735- }
1736- case CBOR_MAJOR_TYPE . BYTE_STRING : {
1737- const { bytesConsumed : b , item : it } = decodeBytesWithLengthSync ( data )
1738- item = it
1739- bytesConsumed = b
1740- break
1741- }
1742- case CBOR_MAJOR_TYPE . TEXT_STRING : {
1743- const { bytesConsumed : b , item : it } = decodeTextWithLengthSync ( data )
1744- item = it
1745- bytesConsumed = b
1746- break
1747- }
1748- case CBOR_MAJOR_TYPE . ARRAY : {
1749- const { bytesConsumed : b , item : it } = decodeArrayWithLengthSync ( data , options )
1750- item = it
1751- bytesConsumed = b
1752- break
1753- }
1754- case CBOR_MAJOR_TYPE . MAP : {
1755- const { bytesConsumed : b , item : it } = decodeMapWithLengthSync ( data , options )
1756- item = it
1757- bytesConsumed = b
1758- break
1759- }
1760- case CBOR_MAJOR_TYPE . TAG : {
1761- const { bytesConsumed : b , item : it } = decodeTagWithLengthSync ( data , options )
1762- item = it
1763- bytesConsumed = b
1764- break
1765- }
1766- case CBOR_MAJOR_TYPE . SIMPLE_FLOAT : {
1767- item = decodeSimpleOrFloatSync ( data )
1768- const additionalInfo = firstByte & 0x1f
1769- bytesConsumed =
1770- additionalInfo < 24 ? 1 : additionalInfo === 24 ? 2 : additionalInfo === 25 ? 3 : additionalInfo === 26 ? 5 : 9
1771- break
1772- }
1773- default :
1774- throw new CBORError ( { message : `Unsupported major type: ${ majorType } ` } )
1775- }
1776- return { item, bytesConsumed }
1777- }
1778-
1779- const decodeArrayWithLengthSync = ( data : Uint8Array , options : CodecOptions ) : { item : CBOR ; bytesConsumed : number } => {
1780- const firstByte = data [ 0 ]
1781- const additionalInfo = firstByte & 0x1f
1782- if ( additionalInfo === CBOR_ADDITIONAL_INFO . INDEFINITE ) {
1783- const result : Array < CBOR > = [ ]
1784- let offset = 1
1785- while ( offset < data . length ) {
1786- if ( data [ offset ] === 0xff ) {
1787- offset ++
1788- break
1789- }
1790- const { bytesConsumed, item } = decodeItemWithLengthSync ( data . slice ( offset ) , options )
1791- result . push ( item )
1792- offset += bytesConsumed
1793- }
1794- return { item : result , bytesConsumed : offset }
1795- } else {
1796- const { bytesRead, length } = decodeLengthSync ( data , 0 )
1797- const result : Array < CBOR > = [ ]
1798- let offset = bytesRead
1799- for ( let i = 0 ; i < length ; i ++ ) {
1800- const { bytesConsumed, item } = decodeItemWithLengthSync ( data . slice ( offset ) , options )
1801- result . push ( item )
1802- offset += bytesConsumed
1803- }
1804- return { item : result , bytesConsumed : offset }
1805- }
1806- }
1807-
1808- const decodeMapWithLengthSync = ( data : Uint8Array , options : CodecOptions ) : { item : CBOR ; bytesConsumed : number } => {
1809- const firstByte = data [ 0 ]
1810- const additionalInfo = firstByte & 0x1f
1811- if ( additionalInfo === CBOR_ADDITIONAL_INFO . INDEFINITE ) {
1812- const result =
1813- options . mode === "custom" && options . mapsAsObjects ? ( { } as Record < string , CBOR > ) : new Map < CBOR , CBOR > ( )
1814- let offset = 1
1815- while ( offset < data . length ) {
1816- if ( data [ offset ] === 0xff ) {
1817- offset ++
1818- break
1819- }
1820- const { bytesConsumed : keyBytes , item : key } = decodeItemWithLengthSync ( data . slice ( offset ) , options )
1821- offset += keyBytes
1822- const { bytesConsumed : valueBytes , item : value } = decodeItemWithLengthSync ( data . slice ( offset ) , options )
1823- offset += valueBytes
1824- if ( result instanceof Map ) {
1825- result . set ( key , value )
1826- } else {
1827- result [ String ( key as any ) ] = value
1828- }
1829- }
1830- return { item : result , bytesConsumed : offset }
1831- } else {
1832- const { bytesRead, length } = decodeLengthSync ( data , 0 )
1833- const result =
1834- options . mode === "custom" && options . mapsAsObjects ? ( { } as Record < string , CBOR > ) : new Map < CBOR , CBOR > ( )
1835- let offset = bytesRead
1836- for ( let i = 0 ; i < length ; i ++ ) {
1837- const { bytesConsumed : keyBytes , item : key } = decodeItemWithLengthSync ( data . slice ( offset ) , options )
1838- offset += keyBytes
1839- const { bytesConsumed : valueBytes , item : value } = decodeItemWithLengthSync ( data . slice ( offset ) , options )
1840- offset += valueBytes
1841- if ( result instanceof Map ) {
1842- result . set ( key , value )
1843- } else {
1844- result [ String ( key as any ) ] = value
1845- }
1846- }
1847- return { item : result , bytesConsumed : offset }
1848- }
1849- }
1850-
1851- const decodeTagWithLengthSync = ( data : Uint8Array , options : CodecOptions ) : { item : CBOR ; bytesConsumed : number } => {
1852- const firstByte = data [ 0 ]
1853- const additionalInfo = firstByte & 0x1f
1854- let tag : number
1855- let dataOffset : number
1856- if ( additionalInfo < 24 ) {
1857- tag = additionalInfo
1858- dataOffset = 1
1859- } else if ( additionalInfo === 24 ) {
1860- if ( data . length < 2 ) throw new CBORError ( { message : "Insufficient data for 1-byte tag" } )
1861- tag = data [ 1 ]
1862- dataOffset = 2
1863- } else if ( additionalInfo === 25 ) {
1864- if ( data . length < 3 ) throw new CBORError ( { message : "Insufficient data for 2-byte tag" } )
1865- tag = data [ 1 ] * 256 + data [ 2 ]
1866- dataOffset = 3
1867- } else {
1868- throw new CBORError ( { message : `Unsupported additional info for tag: ${ additionalInfo } ` } )
1869- }
1870- const { bytesConsumed, item : innerValue } = decodeItemWithLengthSync ( data . slice ( dataOffset ) , options )
1871- if ( tag === 2 || tag === 3 ) {
1872- if ( ! ( innerValue instanceof Uint8Array ) ) throw new CBORError ( { message : `Invalid value for bigint tag ${ tag } ` } )
1873- const bigintValue = ( ( ) => {
1874- let result = 0n
1875- for ( let i = 0 ; i < innerValue . length ; i ++ ) result = ( result << 8n ) + BigInt ( innerValue [ i ] )
1876- return tag === 2 ? result : - 1n - result
1877- } ) ( )
1878- return { item : bigintValue , bytesConsumed : dataOffset + bytesConsumed }
1879- }
1880- return { item : { _tag : "Tag" , tag, value : innerValue } , bytesConsumed : dataOffset + bytesConsumed }
1881- }
1882-
1883- const decodeSimpleOrFloatSync = ( data : Uint8Array ) : CBOR => {
1884- const firstByte = data [ 0 ]
1885- const additionalInfo = firstByte & 0x1f
1886- if ( additionalInfo < 20 ) {
1887- // Return unassigned simple values as numbers
1888- return additionalInfo
1889- } else if ( additionalInfo === CBOR_SIMPLE . FALSE ) {
1890- return false
1891- } else if ( additionalInfo === CBOR_SIMPLE . TRUE ) {
1892- return true
1893- } else if ( additionalInfo === CBOR_SIMPLE . NULL ) {
1894- return null
1895- } else if ( additionalInfo === CBOR_SIMPLE . UNDEFINED ) {
1896- return undefined
1897- } else if ( additionalInfo === CBOR_ADDITIONAL_INFO . DIRECT ) {
1898- if ( data . length < 2 ) throw new CBORError ( { message : "Insufficient data for simple value (one byte)" } )
1899- const simpleValue = data [ 1 ]
1900- return simpleValue
1901- } else if ( additionalInfo === CBOR_ADDITIONAL_INFO . UINT16 ) {
1902- if ( data . length < 3 ) throw new CBORError ( { message : "Insufficient data for half-precision float" } )
1903- const value = ( data [ 1 ] << 8 ) | data [ 2 ]
1904- const float = decodeFloat16 ( value )
1905- return float
1906- } else if ( additionalInfo === CBOR_ADDITIONAL_INFO . UINT32 ) {
1907- if ( data . length < 5 ) throw new CBORError ( { message : "Insufficient data for single-precision float" } )
1908- const buffer = data . slice ( 1 , 5 )
1909- const view = new DataView ( buffer . buffer , buffer . byteOffset , buffer . byteLength )
1910- return view . getFloat32 ( 0 , false )
1911- } else if ( additionalInfo === CBOR_ADDITIONAL_INFO . UINT64 ) {
1912- if ( data . length < 9 ) throw new CBORError ( { message : "Insufficient data for double-precision float" } )
1913- const buffer = data . slice ( 1 , 9 )
1914- const view = new DataView ( buffer . buffer , buffer . byteOffset , buffer . byteLength )
1915- return view . getFloat64 ( 0 , false )
1916- }
1917- throw new CBORError ( { message : `Unsupported additional info for simple/float: ${ additionalInfo } ` } )
1918- }
1919-
1920- const decodeLengthSync = ( data : Uint8Array , offset : number ) : { length : number ; bytesRead : number } => {
1921- const firstByte = data [ offset ]
1922- const majorType = ( firstByte >> 5 ) & 0x07
1923- const additionalInfo = firstByte & 0x1f
1924- let length = 0
1925- let bytesRead = 0
1926- if (
1927- majorType !== CBOR_MAJOR_TYPE . BYTE_STRING &&
1928- majorType !== CBOR_MAJOR_TYPE . TEXT_STRING &&
1929- majorType !== CBOR_MAJOR_TYPE . ARRAY &&
1930- majorType !== CBOR_MAJOR_TYPE . MAP
1931- ) {
1932- throw new CBORError ( { message : `Invalid major type for length decoding: ${ majorType } ` } )
1933- }
1934- if ( additionalInfo < 24 ) {
1935- length = additionalInfo
1936- bytesRead = 1
1937- } else if ( additionalInfo === 24 ) {
1938- if ( data . length < offset + 2 ) throw new CBORError ( { message : "Insufficient data for 1-byte length" } )
1939- length = data [ offset + 1 ]
1940- bytesRead = 2
1941- } else if ( additionalInfo === 25 ) {
1942- if ( data . length < offset + 3 ) throw new CBORError ( { message : "Insufficient data for 2-byte length" } )
1943- length = data [ offset + 1 ] * 256 + data [ offset + 2 ]
1944- bytesRead = 3
1945- } else if ( additionalInfo === 26 ) {
1946- if ( data . length < offset + 5 ) throw new CBORError ( { message : "Insufficient data for 4-byte length" } )
1947- length = ( data [ offset + 1 ] << 24 ) | ( data [ offset + 2 ] << 16 ) | ( data [ offset + 3 ] << 8 ) | data [ offset + 4 ]
1948- bytesRead = 5
1949- } else {
1950- throw new CBORError ( { message : `Unsupported additional info for length: ${ additionalInfo } ` } )
1951- }
1952- return { length, bytesRead }
1953- }
0 commit comments