@transia/ripple-binary-codec 1.4.6-alpha.8 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/binary.d.ts +30 -16
- package/dist/binary.js +36 -16
- package/dist/binary.js.map +1 -1
- package/dist/enums/bytes.d.ts +1 -2
- package/dist/enums/bytes.js +3 -2
- package/dist/enums/bytes.js.map +1 -1
- package/dist/enums/constants.d.ts +1 -0
- package/dist/enums/constants.js +6 -5
- package/dist/enums/constants.js.map +1 -1
- package/dist/enums/definitions.json +1650 -964
- package/dist/enums/field.d.ts +1 -2
- package/dist/enums/field.js +1 -2
- package/dist/enums/field.js.map +1 -1
- package/dist/enums/index.d.ts +1 -2
- package/dist/enums/index.js +5 -27
- package/dist/enums/index.js.map +1 -1
- package/dist/enums/src/enums/definitions.json +1652 -966
- package/dist/enums/xrpl-definitions-base.d.ts +5 -3
- package/dist/enums/xrpl-definitions-base.js +26 -6
- package/dist/enums/xrpl-definitions-base.js.map +1 -1
- package/dist/enums/xrpl-definitions.d.ts +2 -1
- package/dist/enums/xrpl-definitions.js +2 -1
- package/dist/enums/xrpl-definitions.js.map +1 -1
- package/dist/hash-prefixes.d.ts +1 -2
- package/dist/hash-prefixes.js +8 -6
- package/dist/hash-prefixes.js.map +1 -1
- package/dist/hashes.d.ts +6 -7
- package/dist/hashes.js +6 -7
- package/dist/hashes.js.map +1 -1
- package/dist/index.d.ts +16 -11
- package/dist/index.js +53 -58
- package/dist/index.js.map +1 -1
- package/dist/ledger-hashes.d.ts +1 -2
- package/dist/ledger-hashes.js +11 -30
- package/dist/ledger-hashes.js.map +1 -1
- package/dist/quality.d.ts +3 -4
- package/dist/quality.js +10 -8
- package/dist/quality.js.map +1 -1
- package/dist/serdes/binary-parser.d.ts +2 -3
- package/dist/serdes/binary-parser.js +16 -32
- package/dist/serdes/binary-parser.js.map +1 -1
- package/dist/serdes/binary-serializer.d.ts +7 -8
- package/dist/serdes/binary-serializer.js +14 -37
- package/dist/serdes/binary-serializer.js.map +1 -1
- package/dist/shamap.d.ts +4 -5
- package/dist/shamap.js +5 -5
- package/dist/shamap.js.map +1 -1
- package/dist/src/binary.d.ts +106 -0
- package/dist/src/binary.js +154 -0
- package/dist/src/binary.js.map +1 -0
- package/dist/src/coretypes.d.ts +9 -0
- package/dist/src/coretypes.js +48 -0
- package/dist/src/coretypes.js.map +1 -0
- package/dist/src/enums/bytes.d.ts +25 -0
- package/dist/src/enums/bytes.js +65 -0
- package/dist/src/enums/bytes.js.map +1 -0
- package/dist/src/enums/constants.d.ts +5 -0
- package/dist/src/enums/constants.js +9 -0
- package/dist/src/enums/constants.js.map +1 -0
- package/dist/src/enums/definitions.json +3404 -0
- package/dist/src/enums/field.d.ts +28 -0
- package/dist/src/enums/field.js +58 -0
- package/dist/src/enums/field.js.map +1 -0
- package/dist/src/enums/index.d.ts +12 -0
- package/dist/src/enums/index.js +31 -0
- package/dist/src/enums/index.js.map +1 -0
- package/dist/src/enums/utils-renumber.d.ts +101 -0
- package/dist/src/enums/utils-renumber.js +127 -0
- package/dist/src/enums/utils-renumber.js.map +1 -0
- package/dist/src/enums/xrpl-definitions-base.d.ts +47 -0
- package/dist/src/enums/xrpl-definitions-base.js +83 -0
- package/dist/src/enums/xrpl-definitions-base.js.map +1 -0
- package/dist/src/enums/xrpl-definitions.d.ts +22 -0
- package/dist/src/enums/xrpl-definitions.js +30 -0
- package/dist/src/enums/xrpl-definitions.js.map +1 -0
- package/dist/src/hash-prefixes.d.ts +5 -0
- package/dist/src/hash-prefixes.js +43 -0
- package/dist/src/hash-prefixes.js.map +1 -0
- package/dist/src/hashes.d.ts +50 -0
- package/dist/src/hashes.js +76 -0
- package/dist/src/hashes.js.map +1 -0
- package/dist/src/index.d.ts +69 -0
- package/dist/src/index.js +134 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/ledger-hashes.d.ts +48 -0
- package/dist/src/ledger-hashes.js +141 -0
- package/dist/src/ledger-hashes.js.map +1 -0
- package/dist/src/quality.d.ts +21 -0
- package/dist/src/quality.js +42 -0
- package/dist/src/quality.js.map +1 -0
- package/dist/src/serdes/binary-parser.d.ts +100 -0
- package/dist/src/serdes/binary-parser.js +194 -0
- package/dist/src/serdes/binary-parser.js.map +1 -0
- package/dist/src/serdes/binary-serializer.d.ts +81 -0
- package/dist/src/serdes/binary-serializer.js +149 -0
- package/dist/src/serdes/binary-serializer.js.map +1 -0
- package/dist/src/shamap.d.ts +102 -0
- package/dist/src/shamap.js +172 -0
- package/dist/src/shamap.js.map +1 -0
- package/dist/src/types/account-id.d.ts +37 -0
- package/dist/src/types/account-id.js +73 -0
- package/dist/src/types/account-id.js.map +1 -0
- package/dist/src/types/amount.d.ts +92 -0
- package/dist/src/types/amount.js +292 -0
- package/dist/src/types/amount.js.map +1 -0
- package/dist/src/types/blob.d.ts +25 -0
- package/dist/src/types/blob.js +46 -0
- package/dist/src/types/blob.js.map +1 -0
- package/dist/src/types/currency.d.ts +30 -0
- package/dist/src/types/currency.js +131 -0
- package/dist/src/types/currency.js.map +1 -0
- package/dist/src/types/data.d.ts +104 -0
- package/dist/src/types/data.js +387 -0
- package/dist/src/types/data.js.map +1 -0
- package/dist/src/types/dataType.d.ts +94 -0
- package/dist/src/types/dataType.js +145 -0
- package/dist/src/types/dataType.js.map +1 -0
- package/dist/src/types/hash-128.d.ts +18 -0
- package/dist/src/types/hash-128.js +36 -0
- package/dist/src/types/hash-128.js.map +1 -0
- package/dist/src/types/hash-160.d.ts +12 -0
- package/dist/src/types/hash-160.js +23 -0
- package/dist/src/types/hash-160.js.map +1 -0
- package/dist/src/types/hash-192.d.ts +12 -0
- package/dist/src/types/hash-192.js +23 -0
- package/dist/src/types/hash-192.js.map +1 -0
- package/dist/src/types/hash-256.d.ts +12 -0
- package/dist/src/types/hash-256.js +20 -0
- package/dist/src/types/hash-256.js.map +1 -0
- package/dist/src/types/hash.d.ts +40 -0
- package/dist/src/types/hash.js +76 -0
- package/dist/src/types/hash.js.map +1 -0
- package/dist/src/types/index.d.ts +21 -0
- package/dist/src/types/index.js +72 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/issue.d.ts +49 -0
- package/dist/src/types/issue.js +107 -0
- package/dist/src/types/issue.js.map +1 -0
- package/dist/src/types/json.d.ts +169 -0
- package/dist/src/types/json.js +529 -0
- package/dist/src/types/json.js.map +1 -0
- package/dist/src/types/path-set.d.ts +37 -0
- package/dist/src/types/path-set.js +236 -0
- package/dist/src/types/path-set.js.map +1 -0
- package/dist/src/types/serialized-type.d.ts +117 -0
- package/dist/src/types/serialized-type.js +242 -0
- package/dist/src/types/serialized-type.js.map +1 -0
- package/dist/src/types/st-array.d.ts +32 -0
- package/dist/src/types/st-array.js +89 -0
- package/dist/src/types/st-array.js.map +1 -0
- package/dist/src/types/st-number.d.ts +55 -0
- package/dist/src/types/st-number.js +212 -0
- package/dist/src/types/st-number.js.map +1 -0
- package/dist/src/types/st-object.d.ts +33 -0
- package/dist/src/types/st-object.js +176 -0
- package/dist/src/types/st-object.js.map +1 -0
- package/dist/src/types/uint-16.d.ts +26 -0
- package/dist/src/types/uint-16.js +49 -0
- package/dist/src/types/uint-16.js.map +1 -0
- package/dist/src/types/uint-32.d.ts +26 -0
- package/dist/src/types/uint-32.js +54 -0
- package/dist/src/types/uint-32.js.map +1 -0
- package/dist/src/types/uint-64.d.ts +40 -0
- package/dist/src/types/uint-64.js +112 -0
- package/dist/src/types/uint-64.js.map +1 -0
- package/dist/src/types/uint-8.d.ts +26 -0
- package/dist/src/types/uint-8.js +50 -0
- package/dist/src/types/uint-8.js.map +1 -0
- package/dist/src/types/uint.d.ts +29 -0
- package/dist/src/types/uint.js +47 -0
- package/dist/src/types/uint.js.map +1 -0
- package/dist/src/types/vector-256.d.ts +31 -0
- package/dist/src/types/vector-256.js +76 -0
- package/dist/src/types/vector-256.js.map +1 -0
- package/dist/src/types/xchain-bridge.d.ts +45 -0
- package/dist/src/types/xchain-bridge.js +105 -0
- package/dist/src/types/xchain-bridge.js.map +1 -0
- package/dist/src/utils.d.ts +79 -0
- package/dist/src/utils.js +181 -0
- package/dist/src/utils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/account-id.d.ts +3 -2
- package/dist/types/account-id.js +8 -6
- package/dist/types/account-id.js.map +1 -1
- package/dist/types/amount.d.ts +33 -9
- package/dist/types/amount.js +128 -43
- package/dist/types/amount.js.map +1 -1
- package/dist/types/blob.d.ts +3 -3
- package/dist/types/blob.js +8 -2
- package/dist/types/blob.js.map +1 -1
- package/dist/types/currency.d.ts +3 -2
- package/dist/types/currency.js +17 -13
- package/dist/types/currency.js.map +1 -1
- package/dist/types/data.d.ts +104 -0
- package/dist/types/data.js +387 -0
- package/dist/types/data.js.map +1 -0
- package/dist/types/dataType.d.ts +94 -0
- package/dist/types/dataType.js +145 -0
- package/dist/types/dataType.js.map +1 -0
- package/dist/types/hash-128.d.ts +3 -2
- package/dist/types/hash-128.js +7 -3
- package/dist/types/hash-128.js.map +1 -1
- package/dist/types/hash-160.d.ts +3 -2
- package/dist/types/hash-160.js +5 -2
- package/dist/types/hash-160.js.map +1 -1
- package/dist/types/hash-192.d.ts +12 -0
- package/dist/types/hash-192.js +23 -0
- package/dist/types/hash-192.js.map +1 -0
- package/dist/types/hash-256.d.ts +3 -2
- package/dist/types/hash-256.js +5 -2
- package/dist/types/hash-256.js.map +1 -1
- package/dist/types/hash.d.ts +2 -3
- package/dist/types/hash.js +8 -4
- package/dist/types/hash.js.map +1 -1
- package/dist/types/index.d.ts +4 -1
- package/dist/types/index.js +17 -2
- package/dist/types/index.js.map +1 -1
- package/dist/types/issue.d.ts +49 -0
- package/dist/types/issue.js +107 -0
- package/dist/types/issue.js.map +1 -0
- package/dist/types/json.d.ts +169 -0
- package/dist/types/json.js +529 -0
- package/dist/types/json.js.map +1 -0
- package/dist/types/path-set.d.ts +2 -1
- package/dist/types/path-set.js +15 -12
- package/dist/types/path-set.js.map +1 -1
- package/dist/types/serialized-type.d.ts +70 -16
- package/dist/types/serialized-type.js +153 -8
- package/dist/types/serialized-type.js.map +1 -1
- package/dist/types/st-array.d.ts +7 -3
- package/dist/types/st-array.js +20 -11
- package/dist/types/st-array.js.map +1 -1
- package/dist/types/st-number.d.ts +55 -0
- package/dist/types/st-number.js +212 -0
- package/dist/types/st-number.js.map +1 -0
- package/dist/types/st-object.d.ts +2 -1
- package/dist/types/st-object.js +35 -8
- package/dist/types/st-object.js.map +1 -1
- package/dist/types/uint-16.d.ts +3 -2
- package/dist/types/uint-16.js +10 -5
- package/dist/types/uint-16.js.map +1 -1
- package/dist/types/uint-32.d.ts +3 -2
- package/dist/types/uint-32.js +11 -6
- package/dist/types/uint-32.js.map +1 -1
- package/dist/types/uint-64.d.ts +8 -7
- package/dist/types/uint-64.js +49 -24
- package/dist/types/uint-64.js.map +1 -1
- package/dist/types/uint-8.d.ts +3 -2
- package/dist/types/uint-8.js +11 -5
- package/dist/types/uint-8.js.map +1 -1
- package/dist/types/uint.d.ts +5 -6
- package/dist/types/uint.js +5 -0
- package/dist/types/uint.js.map +1 -1
- package/dist/types/vector-256.d.ts +3 -3
- package/dist/types/vector-256.js +5 -4
- package/dist/types/vector-256.js.map +1 -1
- package/dist/types/xchain-bridge.d.ts +45 -0
- package/dist/types/xchain-bridge.js +105 -0
- package/dist/types/xchain-bridge.js.map +1 -0
- package/dist/utils.d.ts +79 -0
- package/dist/utils.js +181 -0
- package/dist/utils.js.map +1 -0
- package/package.json +21 -17
- package/src/README.md +5 -0
- package/src/binary.ts +235 -0
- package/src/coretypes.ts +31 -0
- package/src/enums/README.md +144 -0
- package/src/enums/bytes.ts +80 -0
- package/src/enums/constants.ts +5 -0
- package/src/enums/definitions.json +3409 -0
- package/src/enums/field.ts +84 -0
- package/src/enums/index.ts +34 -0
- package/src/enums/utils-renumber.ts +134 -0
- package/src/enums/xrpl-definitions-base.ts +150 -0
- package/src/enums/xrpl-definitions.ts +33 -0
- package/src/hash-prefixes.ts +42 -0
- package/src/hashes.ts +75 -0
- package/src/index.ts +166 -0
- package/src/ledger-hashes.ts +191 -0
- package/src/quality.ts +38 -0
- package/src/serdes/binary-parser.ts +228 -0
- package/src/serdes/binary-serializer.ts +166 -0
- package/src/shamap.ts +189 -0
- package/src/types/account-id.ts +91 -0
- package/src/types/amount.ts +366 -0
- package/src/types/blob.ts +50 -0
- package/src/types/currency.ts +145 -0
- package/src/types/data.ts +496 -0
- package/src/types/dataType.ts +178 -0
- package/src/types/hash-128.ts +38 -0
- package/src/types/hash-160.ts +24 -0
- package/src/types/hash-192.ts +24 -0
- package/src/types/hash-256.ts +20 -0
- package/src/types/hash.ts +86 -0
- package/src/types/index.ts +74 -0
- package/src/types/issue.ts +140 -0
- package/src/types/json.ts +641 -0
- package/src/types/path-set.ts +294 -0
- package/src/types/serialized-type.ts +271 -0
- package/src/types/st-array.ts +117 -0
- package/src/types/st-number.ts +238 -0
- package/src/types/st-object.ts +219 -0
- package/src/types/uint-16.ts +58 -0
- package/src/types/uint-32.ts +64 -0
- package/src/types/uint-64.ts +141 -0
- package/src/types/uint-8.ts +57 -0
- package/src/types/uint.ts +60 -0
- package/src/types/vector-256.ts +83 -0
- package/src/types/xchain-bridge.ts +132 -0
- package/src/utils.ts +220 -0
- package/test/amount.test.js +0 -43
- package/test/binary-json.test.js +0 -45
- package/test/binary-parser.test.js +0 -396
- package/test/binary-serializer.test.js +0 -307
- package/test/definitions.test.js +0 -100
- package/test/fixtures/account-tx-transactions.db +0 -0
- package/test/fixtures/codec-fixtures.json +0 -4466
- package/test/fixtures/data-driven-tests.json +0 -2919
- package/test/fixtures/delivermin-tx-binary.json +0 -1
- package/test/fixtures/delivermin-tx.json +0 -98
- package/test/fixtures/deposit-preauth-tx-binary.json +0 -1
- package/test/fixtures/deposit-preauth-tx-meta-binary.json +0 -1
- package/test/fixtures/deposit-preauth-tx.json +0 -58
- package/test/fixtures/escrow-cancel-binary.json +0 -1
- package/test/fixtures/escrow-cancel-tx.json +0 -6
- package/test/fixtures/escrow-create-binary.json +0 -1
- package/test/fixtures/escrow-create-tx.json +0 -10
- package/test/fixtures/escrow-finish-binary.json +0 -1
- package/test/fixtures/escrow-finish-meta-binary.json +0 -1
- package/test/fixtures/escrow-finish-tx.json +0 -95
- package/test/fixtures/ledger-full-38129.json +0 -1
- package/test/fixtures/ledger-full-40000.json +0 -1
- package/test/fixtures/negative-unl.json +0 -12
- package/test/fixtures/nf-token.json +0 -547
- package/test/fixtures/payment-channel-claim-binary.json +0 -1
- package/test/fixtures/payment-channel-claim-tx.json +0 -8
- package/test/fixtures/payment-channel-create-binary.json +0 -1
- package/test/fixtures/payment-channel-create-tx.json +0 -11
- package/test/fixtures/payment-channel-fund-binary.json +0 -1
- package/test/fixtures/payment-channel-fund-tx.json +0 -7
- package/test/fixtures/signerlistset-tx-binary.json +0 -1
- package/test/fixtures/signerlistset-tx-meta-binary.json +0 -1
- package/test/fixtures/signerlistset-tx.json +0 -94
- package/test/fixtures/ticket-create-binary.json +0 -1
- package/test/fixtures/ticket-create-tx.json +0 -7
- package/test/fixtures/unl-report-binary.json +0 -1
- package/test/fixtures/unl-report-meta-binary.json +0 -1
- package/test/fixtures/unl-report.json +0 -89
- package/test/fixtures/x-codec-fixtures.json +0 -188
- package/test/hash.test.js +0 -135
- package/test/ledger.test.js +0 -29
- package/test/lower-case-hex.test.js +0 -46
- package/test/pseudo-transaction.test.js +0 -38
- package/test/quality.test.js +0 -15
- package/test/shamap.test.js +0 -89
- package/test/signing-data-encoding.test.js +0 -213
- package/test/tx-encode-decode.test.js +0 -119
- package/test/types.test.js +0 -34
- package/test/uint.test.js +0 -148
- package/test/utils.js +0 -30
- package/test/x-address.test.js +0 -181
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { BinaryParser } from '../serdes/binary-parser'
|
|
2
|
+
import { SerializedType, SerializedTypeID } from './serialized-type'
|
|
3
|
+
import { writeInt32BE, writeInt64BE, readInt32BE, readInt64BE } from '../utils'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Constants for mantissa and exponent normalization per XRPL Number spec.
|
|
7
|
+
* These define allowed magnitude for mantissa and exponent after normalization.
|
|
8
|
+
*/
|
|
9
|
+
const MIN_MANTISSA = BigInt('1000000000000000')
|
|
10
|
+
const MAX_MANTISSA = BigInt('9999999999999999')
|
|
11
|
+
const MIN_EXPONENT = -32768
|
|
12
|
+
const MAX_EXPONENT = 32768
|
|
13
|
+
const DEFAULT_VALUE_EXPONENT = -2147483648
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Extract mantissa, exponent, and sign from a number string.
|
|
17
|
+
*
|
|
18
|
+
* @param val - The string representing the number (may be integer, decimal, or scientific notation).
|
|
19
|
+
* @returns Object containing mantissa (BigInt), exponent (number), and isNegative (boolean).
|
|
20
|
+
* @throws Error if the string cannot be parsed as a valid number.
|
|
21
|
+
*
|
|
22
|
+
* Examples:
|
|
23
|
+
* '123' -> { mantissa: 123n, exponent: 0, isNegative: false }
|
|
24
|
+
* '-00123.45' -> { mantissa: -12345n, exponent: -2, isNegative: true }
|
|
25
|
+
* '+7.1e2' -> { mantissa: 71n, exponent: -1 + 2 = 1, isNegative: false }
|
|
26
|
+
*/
|
|
27
|
+
function extractNumberPartsFromString(val: string): {
|
|
28
|
+
mantissa: bigint
|
|
29
|
+
exponent: number
|
|
30
|
+
isNegative: boolean
|
|
31
|
+
} {
|
|
32
|
+
/**
|
|
33
|
+
* Regex for parsing decimal/float/scientific number strings with optional sign, integer, decimal, and exponent parts.
|
|
34
|
+
*
|
|
35
|
+
* Pattern: /^([-+]?)([0-9]+)(?:\.([0-9]+))?(?:[eE]([+-]?[0-9]+))?$/
|
|
36
|
+
*
|
|
37
|
+
* Breakdown:
|
|
38
|
+
* 1. ([-+]?) - Optional '+' or '-' sign at the start.
|
|
39
|
+
* 2. ([0-9]+) - Integer part: one or more digits (leading zeros allowed).
|
|
40
|
+
* 3. (?:\.([0-9]+))? - Optional decimal point followed by one or more digits.
|
|
41
|
+
* 4. (?:[eE]([+-]?[0-9]+))? - Optional exponent, starting with 'e' or 'E', optional sign, and digits.
|
|
42
|
+
*
|
|
43
|
+
* Notes:
|
|
44
|
+
* - Leading zeros are accepted and normalized by code after parsing.
|
|
45
|
+
* - Empty decimal ('123.') and missing integer ('.456') are NOT matched—must be fully specified.
|
|
46
|
+
*/
|
|
47
|
+
// eslint-disable-next-line prefer-named-capture-group
|
|
48
|
+
const regex = /^([-+]?)([0-9]+)(?:\.([0-9]+))?(?:[eE]([+-]?[0-9]+))?$/
|
|
49
|
+
const match = regex.exec(val)
|
|
50
|
+
if (!match) throw new Error(`Unable to parse number from string: ${val}`)
|
|
51
|
+
|
|
52
|
+
const [, sign, intPart, fracPart, expPart] = match
|
|
53
|
+
// Remove leading zeros (unless the entire intPart is zeros)
|
|
54
|
+
const cleanIntPart = intPart.replace(/^0+(?=\d)/, '') || '0'
|
|
55
|
+
|
|
56
|
+
let mantissaStr = cleanIntPart
|
|
57
|
+
let exponent = 0
|
|
58
|
+
|
|
59
|
+
if (fracPart) {
|
|
60
|
+
mantissaStr += fracPart
|
|
61
|
+
exponent -= fracPart.length
|
|
62
|
+
}
|
|
63
|
+
if (expPart) exponent += parseInt(expPart, 10)
|
|
64
|
+
|
|
65
|
+
let mantissa = BigInt(mantissaStr)
|
|
66
|
+
if (sign === '-') mantissa = -mantissa
|
|
67
|
+
const isNegative = mantissa < BigInt(0)
|
|
68
|
+
|
|
69
|
+
return { mantissa, exponent, isNegative }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Normalize the mantissa and exponent to XRPL constraints.
|
|
74
|
+
*
|
|
75
|
+
* Ensures that after normalization, the mantissa is between MIN_MANTISSA and MAX_MANTISSA (unless zero).
|
|
76
|
+
* Adjusts the exponent as needed by shifting the mantissa left/right (multiplying/dividing by 10).
|
|
77
|
+
*
|
|
78
|
+
* @param mantissa - The unnormalized mantissa (BigInt).
|
|
79
|
+
* @param exponent - The unnormalized exponent (number).
|
|
80
|
+
* @returns An object with normalized mantissa and exponent.
|
|
81
|
+
* @throws Error if the number cannot be normalized within allowed exponent range.
|
|
82
|
+
*/
|
|
83
|
+
function normalize(
|
|
84
|
+
mantissa: bigint,
|
|
85
|
+
exponent: number,
|
|
86
|
+
): { mantissa: bigint; exponent: number } {
|
|
87
|
+
let m = mantissa < BigInt(0) ? -mantissa : mantissa
|
|
88
|
+
const isNegative = mantissa < BigInt(0)
|
|
89
|
+
|
|
90
|
+
while (m !== BigInt(0) && m < MIN_MANTISSA && exponent > MIN_EXPONENT) {
|
|
91
|
+
exponent -= 1
|
|
92
|
+
m *= BigInt(10)
|
|
93
|
+
}
|
|
94
|
+
while (m > MAX_MANTISSA) {
|
|
95
|
+
if (exponent >= MAX_EXPONENT)
|
|
96
|
+
throw new Error('Mantissa and exponent are too large')
|
|
97
|
+
exponent += 1
|
|
98
|
+
m /= BigInt(10)
|
|
99
|
+
}
|
|
100
|
+
if (isNegative) m = -m
|
|
101
|
+
return { mantissa: m, exponent }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* STNumber: Encodes XRPL's "Number" type.
|
|
106
|
+
*
|
|
107
|
+
* - Always encoded as 12 bytes: 8-byte signed mantissa, 4-byte signed exponent, both big-endian.
|
|
108
|
+
* - Can only be constructed from a valid number string or another STNumber instance.
|
|
109
|
+
*
|
|
110
|
+
* Usage:
|
|
111
|
+
* STNumber.from("1.2345e5")
|
|
112
|
+
* STNumber.from("-123")
|
|
113
|
+
* STNumber.fromParser(parser)
|
|
114
|
+
*/
|
|
115
|
+
export class STNumber extends SerializedType {
|
|
116
|
+
/** 12 zero bytes, represents canonical zero. */
|
|
117
|
+
static defaultBytes = new Uint8Array(12)
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Construct a STNumber from 12 bytes (8 for mantissa, 4 for exponent).
|
|
121
|
+
* @param bytes - 12-byte Uint8Array
|
|
122
|
+
* @throws Error if input is not a Uint8Array of length 12.
|
|
123
|
+
*/
|
|
124
|
+
constructor(bytes?: Uint8Array) {
|
|
125
|
+
const used = bytes ?? STNumber.defaultBytes
|
|
126
|
+
if (!(used instanceof Uint8Array) || used.length !== 12) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
`STNumber must be constructed from a 12-byte Uint8Array, got ${used?.length}`,
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
super(used)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Construct from a number string (or another STNumber).
|
|
136
|
+
*
|
|
137
|
+
* @param value - A string, or STNumber instance.
|
|
138
|
+
* @returns STNumber instance.
|
|
139
|
+
* @throws Error if not a string or STNumber.
|
|
140
|
+
*/
|
|
141
|
+
static from(value: unknown): STNumber {
|
|
142
|
+
if (value instanceof STNumber) {
|
|
143
|
+
return value
|
|
144
|
+
}
|
|
145
|
+
if (typeof value === 'string') {
|
|
146
|
+
return STNumber.fromValue(value)
|
|
147
|
+
}
|
|
148
|
+
throw new Error(
|
|
149
|
+
'STNumber.from: Only string or STNumber instance is supported',
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Construct from a number string (integer, decimal, or scientific notation).
|
|
155
|
+
* Handles normalization to XRPL Number constraints.
|
|
156
|
+
*
|
|
157
|
+
* @param val - The number as a string (e.g. '1.23', '-123e5').
|
|
158
|
+
* @returns STNumber instance
|
|
159
|
+
* @throws Error if val is not a valid number string.
|
|
160
|
+
*/
|
|
161
|
+
static fromValue(val: string): STNumber {
|
|
162
|
+
const { mantissa, exponent, isNegative } = extractNumberPartsFromString(val)
|
|
163
|
+
let normalizedMantissa: bigint
|
|
164
|
+
let normalizedExponent: number
|
|
165
|
+
|
|
166
|
+
if (mantissa === BigInt(0) && exponent === 0 && !isNegative) {
|
|
167
|
+
normalizedMantissa = BigInt(0)
|
|
168
|
+
normalizedExponent = DEFAULT_VALUE_EXPONENT
|
|
169
|
+
} else {
|
|
170
|
+
;({ mantissa: normalizedMantissa, exponent: normalizedExponent } =
|
|
171
|
+
normalize(mantissa, exponent))
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const bytes = new Uint8Array(12)
|
|
175
|
+
writeInt64BE(bytes, normalizedMantissa, 0)
|
|
176
|
+
writeInt32BE(bytes, normalizedExponent, 8)
|
|
177
|
+
return new STNumber(bytes)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Read a STNumber from a BinaryParser stream (12 bytes).
|
|
182
|
+
* @param parser - BinaryParser positioned at the start of a number
|
|
183
|
+
* @returns STNumber instance
|
|
184
|
+
*/
|
|
185
|
+
static fromParser(parser: BinaryParser): STNumber {
|
|
186
|
+
return new STNumber(parser.read(12))
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Convert this STNumber to a normalized string representation.
|
|
191
|
+
* The output is decimal or scientific notation, depending on exponent range.
|
|
192
|
+
* Follows XRPL convention: zero is "0", other values are normalized to a canonical string.
|
|
193
|
+
*
|
|
194
|
+
* @returns String representation of the value
|
|
195
|
+
*/
|
|
196
|
+
// eslint-disable-next-line complexity -- required
|
|
197
|
+
toJSON(): string {
|
|
198
|
+
const b = this.bytes
|
|
199
|
+
if (!b || b.length !== 12)
|
|
200
|
+
throw new Error('STNumber internal bytes not set or wrong length')
|
|
201
|
+
|
|
202
|
+
// Signed 64-bit mantissa
|
|
203
|
+
const mantissa = readInt64BE(b, 0)
|
|
204
|
+
// Signed 32-bit exponent
|
|
205
|
+
const exponent = readInt32BE(b, 8)
|
|
206
|
+
|
|
207
|
+
// Special zero: XRPL encodes canonical zero as mantissa=0, exponent=DEFAULT_VALUE_EXPONENT.
|
|
208
|
+
if (mantissa === BigInt(0) && exponent === DEFAULT_VALUE_EXPONENT) {
|
|
209
|
+
return '0'
|
|
210
|
+
}
|
|
211
|
+
if (exponent === 0) return mantissa.toString()
|
|
212
|
+
|
|
213
|
+
// Use scientific notation for small/large exponents, decimal otherwise
|
|
214
|
+
if (exponent < -25 || exponent > -5) {
|
|
215
|
+
return `${mantissa}e${exponent}`
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Decimal rendering for -25 <= exp <= -5
|
|
219
|
+
const isNegative = mantissa < BigInt(0)
|
|
220
|
+
const mantissaAbs = mantissa < BigInt(0) ? -mantissa : mantissa
|
|
221
|
+
|
|
222
|
+
const padPrefix = 27
|
|
223
|
+
const padSuffix = 23
|
|
224
|
+
const mantissaStr = mantissaAbs.toString()
|
|
225
|
+
const rawValue = '0'.repeat(padPrefix) + mantissaStr + '0'.repeat(padSuffix)
|
|
226
|
+
const OFFSET = exponent + 43
|
|
227
|
+
const integerPart = rawValue.slice(0, OFFSET).replace(/^0+/, '') || '0'
|
|
228
|
+
const fractionPart = rawValue.slice(OFFSET).replace(/0+$/, '')
|
|
229
|
+
|
|
230
|
+
return `${isNegative ? '-' : ''}${integerPart}${
|
|
231
|
+
fractionPart ? '.' + fractionPart : ''
|
|
232
|
+
}`
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
getSType(): SerializedTypeID {
|
|
236
|
+
return SerializedTypeID.STI_NUMBER
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_DEFINITIONS,
|
|
3
|
+
FieldInstance,
|
|
4
|
+
Bytes,
|
|
5
|
+
XrplDefinitionsBase,
|
|
6
|
+
} from '../enums'
|
|
7
|
+
import { SerializedType, JsonObject, SerializedTypeID } from './serialized-type'
|
|
8
|
+
import {
|
|
9
|
+
xAddressToClassicAddress,
|
|
10
|
+
isValidXAddress,
|
|
11
|
+
} from '@transia/ripple-address-codec'
|
|
12
|
+
import { BinaryParser } from '../serdes/binary-parser'
|
|
13
|
+
import { BinarySerializer, BytesList } from '../serdes/binary-serializer'
|
|
14
|
+
|
|
15
|
+
import { STArray } from './st-array'
|
|
16
|
+
import { UInt64 } from './uint-64'
|
|
17
|
+
|
|
18
|
+
const OBJECT_END_MARKER_BYTE = Uint8Array.from([0xe1])
|
|
19
|
+
const OBJECT_END_MARKER = 'ObjectEndMarker'
|
|
20
|
+
const ST_OBJECT = 'STObject'
|
|
21
|
+
const DESTINATION = 'Destination'
|
|
22
|
+
const ACCOUNT = 'Account'
|
|
23
|
+
const SOURCE_TAG = 'SourceTag'
|
|
24
|
+
const DEST_TAG = 'DestinationTag'
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Break down an X-Address into an account and a tag
|
|
28
|
+
*
|
|
29
|
+
* @param field Name of field
|
|
30
|
+
* @param xAddress X-Address corresponding to the field
|
|
31
|
+
*/
|
|
32
|
+
function handleXAddress(field: string, xAddress: string): JsonObject {
|
|
33
|
+
const decoded = xAddressToClassicAddress(xAddress)
|
|
34
|
+
|
|
35
|
+
let tagName
|
|
36
|
+
if (field === DESTINATION) tagName = DEST_TAG
|
|
37
|
+
else if (field === ACCOUNT) tagName = SOURCE_TAG
|
|
38
|
+
else if (decoded.tag !== false)
|
|
39
|
+
throw new Error(`${field} cannot have an associated tag`)
|
|
40
|
+
|
|
41
|
+
return decoded.tag !== false
|
|
42
|
+
? { [field]: decoded.classicAddress, [tagName]: decoded.tag }
|
|
43
|
+
: { [field]: decoded.classicAddress }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Validate that two objects don't both have the same tag fields
|
|
48
|
+
*
|
|
49
|
+
* @param obj1 First object to check for tags
|
|
50
|
+
* @param obj2 Second object to check for tags
|
|
51
|
+
* @throws When both objects have SourceTag or DestinationTag
|
|
52
|
+
*/
|
|
53
|
+
function checkForDuplicateTags(obj1: JsonObject, obj2: JsonObject): void {
|
|
54
|
+
if (!(obj1[SOURCE_TAG] === undefined || obj2[SOURCE_TAG] === undefined))
|
|
55
|
+
throw new Error('Cannot have Account X-Address and SourceTag')
|
|
56
|
+
if (!(obj1[DEST_TAG] === undefined || obj2[DEST_TAG] === undefined))
|
|
57
|
+
throw new Error('Cannot have Destination X-Address and DestinationTag')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Class for Serializing/Deserializing objects
|
|
62
|
+
*/
|
|
63
|
+
class STObject extends SerializedType {
|
|
64
|
+
/**
|
|
65
|
+
* Construct a STObject from a BinaryParser
|
|
66
|
+
*
|
|
67
|
+
* @param parser BinaryParser to read STObject from
|
|
68
|
+
* @returns A STObject object
|
|
69
|
+
*/
|
|
70
|
+
static fromParser(parser: BinaryParser): STObject {
|
|
71
|
+
const list: BytesList = new BytesList()
|
|
72
|
+
const bytes: BinarySerializer = new BinarySerializer(list)
|
|
73
|
+
|
|
74
|
+
while (!parser.end()) {
|
|
75
|
+
const field = parser.readField()
|
|
76
|
+
if (field.name === OBJECT_END_MARKER) {
|
|
77
|
+
break
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const associatedValue = parser.readFieldValue(field)
|
|
81
|
+
|
|
82
|
+
bytes.writeFieldAndValue(field, associatedValue)
|
|
83
|
+
if (field.type.name === ST_OBJECT) {
|
|
84
|
+
bytes.put(OBJECT_END_MARKER_BYTE)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return new STObject(list.toBytes())
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Construct a STObject from a JSON object
|
|
93
|
+
*
|
|
94
|
+
* @param value An object to include
|
|
95
|
+
* @param filter optional, denote which field to include in serialized object
|
|
96
|
+
* @param definitions optional, types and values to use to encode/decode a transaction
|
|
97
|
+
* @returns a STObject object
|
|
98
|
+
*/
|
|
99
|
+
static from<T extends STObject | JsonObject>(
|
|
100
|
+
value: T,
|
|
101
|
+
filter?: (...any) => boolean,
|
|
102
|
+
definitions: XrplDefinitionsBase = DEFAULT_DEFINITIONS,
|
|
103
|
+
): STObject {
|
|
104
|
+
if (value instanceof STObject) {
|
|
105
|
+
return value
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const list: BytesList = new BytesList()
|
|
109
|
+
const bytes: BinarySerializer = new BinarySerializer(list)
|
|
110
|
+
|
|
111
|
+
let isUnlModify = false
|
|
112
|
+
|
|
113
|
+
const xAddressDecoded = Object.entries(value).reduce((acc, [key, val]) => {
|
|
114
|
+
let handled: JsonObject | undefined = undefined
|
|
115
|
+
if (val && isValidXAddress(val.toString())) {
|
|
116
|
+
handled = handleXAddress(key, val.toString())
|
|
117
|
+
checkForDuplicateTags(handled, value)
|
|
118
|
+
}
|
|
119
|
+
return Object.assign(acc, handled ?? { [key]: val })
|
|
120
|
+
}, {})
|
|
121
|
+
|
|
122
|
+
function isValidFieldInstance(
|
|
123
|
+
f: FieldInstance | undefined,
|
|
124
|
+
): f is FieldInstance {
|
|
125
|
+
return (
|
|
126
|
+
f !== undefined &&
|
|
127
|
+
xAddressDecoded[f.name] !== undefined &&
|
|
128
|
+
f.isSerialized
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
let sorted = Object.keys(xAddressDecoded)
|
|
133
|
+
.map((f: string): FieldInstance | undefined => {
|
|
134
|
+
if (!(f in definitions.field)) {
|
|
135
|
+
if (f[0] === f[0].toLowerCase()) return undefined
|
|
136
|
+
throw new Error(`Field ${f} is not defined in the definitions`)
|
|
137
|
+
}
|
|
138
|
+
return definitions.field[f] as FieldInstance
|
|
139
|
+
})
|
|
140
|
+
.filter(isValidFieldInstance)
|
|
141
|
+
.sort((a, b) => {
|
|
142
|
+
return a.ordinal - b.ordinal
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
if (filter !== undefined) {
|
|
146
|
+
sorted = sorted.filter(filter)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
sorted.forEach((field) => {
|
|
150
|
+
const associatedValue =
|
|
151
|
+
field.type.name === ST_OBJECT
|
|
152
|
+
? this.from(xAddressDecoded[field.name], undefined, definitions)
|
|
153
|
+
: field.type.name === 'STArray'
|
|
154
|
+
? STArray.from(xAddressDecoded[field.name], definitions)
|
|
155
|
+
: field.type.name === 'UInt64'
|
|
156
|
+
? UInt64.from(xAddressDecoded[field.name], field.name)
|
|
157
|
+
: field.associatedType?.from
|
|
158
|
+
? field.associatedType.from(xAddressDecoded[field.name])
|
|
159
|
+
: (() => {
|
|
160
|
+
throw new Error(
|
|
161
|
+
`Type ${field.type.name} for field ${field.name} is missing associatedType.from`,
|
|
162
|
+
)
|
|
163
|
+
})()
|
|
164
|
+
|
|
165
|
+
if (associatedValue == undefined) {
|
|
166
|
+
throw new TypeError(
|
|
167
|
+
`Unable to interpret "${field.name}: ${
|
|
168
|
+
xAddressDecoded[field.name]
|
|
169
|
+
}".`,
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if ((associatedValue as unknown as Bytes).name === 'UNLModify') {
|
|
174
|
+
// triggered when the TransactionType field has a value of 'UNLModify'
|
|
175
|
+
isUnlModify = true
|
|
176
|
+
}
|
|
177
|
+
// true when in the UNLModify pseudotransaction (after the transaction type has been processed) and working with the
|
|
178
|
+
// Account field
|
|
179
|
+
// The Account field must not be a part of the UNLModify pseudotransaction encoding, due to a bug in rippled
|
|
180
|
+
const isUnlModifyWorkaround = field.name == 'Account' && isUnlModify
|
|
181
|
+
bytes.writeFieldAndValue(field, associatedValue, isUnlModifyWorkaround)
|
|
182
|
+
if (field.type.name === ST_OBJECT) {
|
|
183
|
+
bytes.put(OBJECT_END_MARKER_BYTE)
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
return new STObject(list.toBytes())
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get the JSON interpretation of this.bytes
|
|
192
|
+
* @param definitions rippled definitions used to parse the values of transaction types and such.
|
|
193
|
+
* Can be customized for sidechains and amendments.
|
|
194
|
+
* @returns a JSON object
|
|
195
|
+
*/
|
|
196
|
+
toJSON(definitions?: XrplDefinitionsBase): JsonObject {
|
|
197
|
+
const objectParser = new BinaryParser(this.toString(), definitions)
|
|
198
|
+
const accumulator = {}
|
|
199
|
+
|
|
200
|
+
while (!objectParser.end()) {
|
|
201
|
+
const field = objectParser.readField()
|
|
202
|
+
if (field.name === OBJECT_END_MARKER) {
|
|
203
|
+
break
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
accumulator[field.name] = objectParser
|
|
207
|
+
.readFieldValue(field)
|
|
208
|
+
.toJSON(definitions, field.name)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return accumulator
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
getSType(): SerializedTypeID {
|
|
215
|
+
return SerializedTypeID.STI_OBJECT
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export { STObject }
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { UInt } from './uint'
|
|
2
|
+
import { BinaryParser } from '../serdes/binary-parser'
|
|
3
|
+
import { readUInt16BE, writeUInt16BE } from '../utils'
|
|
4
|
+
import { SerializedTypeID } from './serialized-type'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Derived UInt class for serializing/deserializing 16 bit UInt
|
|
8
|
+
*/
|
|
9
|
+
class UInt16 extends UInt {
|
|
10
|
+
protected static readonly width: number = 16 / 8 // 2
|
|
11
|
+
static readonly defaultUInt16: UInt16 = new UInt16(
|
|
12
|
+
new Uint8Array(UInt16.width),
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
constructor(bytes: Uint8Array) {
|
|
16
|
+
super(bytes ?? UInt16.defaultUInt16.bytes)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static fromParser(parser: BinaryParser): UInt {
|
|
20
|
+
return new UInt16(parser.read(UInt16.width))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Construct a UInt16 object from a number
|
|
25
|
+
*
|
|
26
|
+
* @param val UInt16 object or number
|
|
27
|
+
*/
|
|
28
|
+
static from<T extends UInt16 | number>(val: T): UInt16 {
|
|
29
|
+
if (val instanceof UInt16) {
|
|
30
|
+
return val
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (typeof val === 'number') {
|
|
34
|
+
UInt16.checkUintRange(val, 0, 0xffff)
|
|
35
|
+
|
|
36
|
+
const buf = new Uint8Array(UInt16.width)
|
|
37
|
+
writeUInt16BE(buf, val, 0)
|
|
38
|
+
return new UInt16(buf)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
throw new Error('Can not construct UInt16 with given value')
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* get the value of a UInt16 object
|
|
46
|
+
*
|
|
47
|
+
* @returns the number represented by this.bytes
|
|
48
|
+
*/
|
|
49
|
+
valueOf(): number {
|
|
50
|
+
return parseInt(readUInt16BE(this.bytes, 0))
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getSType(): SerializedTypeID {
|
|
54
|
+
return SerializedTypeID.STI_UINT16
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { UInt16 }
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { UInt } from './uint'
|
|
2
|
+
import { BinaryParser } from '../serdes/binary-parser'
|
|
3
|
+
import { readUInt32BE, writeUInt32BE } from '../utils'
|
|
4
|
+
import { SerializedTypeID } from './serialized-type'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Derived UInt class for serializing/deserializing 32 bit UInt
|
|
8
|
+
*/
|
|
9
|
+
class UInt32 extends UInt {
|
|
10
|
+
protected static readonly width: number = 32 / 8 // 4
|
|
11
|
+
static readonly defaultUInt32: UInt32 = new UInt32(
|
|
12
|
+
new Uint8Array(UInt32.width),
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
constructor(bytes: Uint8Array) {
|
|
16
|
+
super(bytes ?? UInt32.defaultUInt32.bytes)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static fromParser(parser: BinaryParser): UInt {
|
|
20
|
+
return new UInt32(parser.read(UInt32.width))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Construct a UInt32 object from a number
|
|
25
|
+
*
|
|
26
|
+
* @param val UInt32 object or number
|
|
27
|
+
*/
|
|
28
|
+
static from<T extends UInt32 | number | string>(val: T): UInt32 {
|
|
29
|
+
if (val instanceof UInt32) {
|
|
30
|
+
return val
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const buf = new Uint8Array(UInt32.width)
|
|
34
|
+
|
|
35
|
+
if (typeof val === 'string') {
|
|
36
|
+
const num = Number.parseInt(val)
|
|
37
|
+
writeUInt32BE(buf, num, 0)
|
|
38
|
+
return new UInt32(buf)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (typeof val === 'number') {
|
|
42
|
+
UInt32.checkUintRange(val, 0, 0xffffffff)
|
|
43
|
+
writeUInt32BE(buf, val, 0)
|
|
44
|
+
return new UInt32(buf)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
throw new Error('Cannot construct UInt32 from given value')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* get the value of a UInt32 object
|
|
52
|
+
*
|
|
53
|
+
* @returns the number represented by this.bytes
|
|
54
|
+
*/
|
|
55
|
+
valueOf(): number {
|
|
56
|
+
return parseInt(readUInt32BE(this.bytes, 0), 10)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getSType(): SerializedTypeID {
|
|
60
|
+
return SerializedTypeID.STI_UINT32
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { UInt32 }
|