Skip to content

Commit 8e9d83f

Browse files
committed
feat(core): Add bytesLen and bytesLenUnsafe utilities
1 parent f048ad8 commit 8e9d83f

2 files changed

Lines changed: 61 additions & 1 deletion

File tree

.changeset/eighty-terms-cry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@ckb-ccc/core": patch
3+
---
4+
5+
Add `bytesLen` and `bytesLenUnsafe` utilities

packages/core/src/hex/index.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export type HexLike = BytesLike;
1818
* A valid hexadecimal string:
1919
* - Has at least two characters.
2020
* - Starts with "0x".
21-
* - Has an even length.
21+
* - Has an even length (odd-length hex is considered non-standard).
2222
* - Contains only characters representing digits (0-9) or lowercase letters (a-f) after the "0x" prefix.
2323
*
2424
* @param v - The value to validate as a hexadecimal (ccc.Hex) string.
@@ -58,3 +58,58 @@ export function hexFrom(hex: HexLike): Hex {
5858

5959
return `0x${bytesTo(bytesFrom(hex), "hex")}`;
6060
}
61+
62+
/**
63+
* Return the number of bytes occupied by `hexLike`.
64+
*
65+
* This function efficiently calculates the byte length of hex-like values:
66+
* - For valid Hex strings, uses fast-path `bytesLenUnsafe` helper
67+
* - For other types, `bytesFrom` is used and the resulting `Uint8Array` length is returned
68+
*
69+
* @param hexLike - Hex-like value (Hex string, Uint8Array, ArrayBuffer, or iterable of numbers).
70+
* @returns Byte length of `hexLike`.
71+
*
72+
* @throws May throw if `hexLike` contains invalid byte values when passed to `bytesFrom`.
73+
* @see bytesFrom - Convert values to Bytes (Uint8Array)
74+
* @see bytesLenUnsafe - Fast byte length for valid Hex strings
75+
*
76+
* @example
77+
* ```typescript
78+
* bytesLen("0x48656c6c6f") // 5
79+
* bytesLen(new Uint8Array([1, 2, 3])) // 3
80+
* bytesLen(new ArrayBuffer(4)) // 4
81+
* bytesLen([0x01, 0x02]) // 2
82+
* ```
83+
*
84+
* @note For performance, access `.length` directly on `Bytes` (`Uint8Array`).
85+
* If `bytesFrom(hexLike)` is called for other operations, access `.length` on
86+
* that result instead. This function is only useful when performing no further
87+
* operations on `hexLike`.
88+
*/
89+
export function bytesLen(hexLike: HexLike): number {
90+
if (isHex(hexLike)) {
91+
return bytesLenUnsafe(hexLike);
92+
}
93+
94+
return bytesFrom(hexLike).length;
95+
}
96+
97+
/**
98+
* Returns the byte length of a Hex string without validation.
99+
*
100+
* Accepts only valid Hex (not HexLike). Handles odd-length hex by
101+
* rounding up, matching bytesFrom behavior.
102+
*
103+
* @param hex - A valid Hex string (with "0x" prefix).
104+
* @returns Byte length, rounded up for odd-digit hex.
105+
*
106+
* @example
107+
* ```typescript
108+
* bytesLenUnsafe("0x48656c6c6f") // 5
109+
* bytesLenUnsafe("0x123") // 2 (odd digits → ceiling)
110+
* ```
111+
*/
112+
export function bytesLenUnsafe(hex: Hex): number {
113+
// Rounds up for odd-digit hex. Equivalent to Math.ceil((hex.length - 2) / 2).
114+
return (hex.length - 1) >> 1;
115+
}

0 commit comments

Comments
 (0)