Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 32 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@ Class to iterate through bytes string by parsing individual bytes

### Methods

- [BigInt](#gear-bigint)
- [String](#gear-string)
- [rest](#gear-rest)
- [isEmpty](#gear-isempty)
- [nextByte](#gear-nextbyte)
- [nextBytes](#gear-nextbytes)
Expand All @@ -277,6 +280,26 @@ Class to iterate through bytes string by parsing individual bytes
- [nextUint160](#gear-nextuint160)
- [nextUint256](#gear-nextuint256)

#### :gear: BigInt

| Method | Type |
| ---------- | ---------- |
| `BigInt` | `(bytes: string) => BytesIter<bigint>` |

#### :gear: String

| Method | Type |
| ---------- | ---------- |
| `String` | `(bytes: string) => BytesIter<string>` |

#### :gear: rest

Returns all not consumed bytes

| Method | Type |
| ---------- | ---------- |
| `rest` | `() => T` |

#### :gear: isEmpty

| Method | Type |
Expand All @@ -287,55 +310,55 @@ Class to iterate through bytes string by parsing individual bytes

| Method | Type |
| ---------- | ---------- |
| `nextByte` | `() => bigint` |
| `nextByte` | `() => T` |

#### :gear: nextBytes

| Method | Type |
| ---------- | ---------- |
| `nextBytes` | `(n: number) => bigint` |
| `nextBytes` | `(n: number) => T` |

#### :gear: nextUint8

| Method | Type |
| ---------- | ---------- |
| `nextUint8` | `() => bigint` |
| `nextUint8` | `() => T` |

#### :gear: nextUint16

| Method | Type |
| ---------- | ---------- |
| `nextUint16` | `() => bigint` |
| `nextUint16` | `() => T` |

#### :gear: nextUint24

| Method | Type |
| ---------- | ---------- |
| `nextUint24` | `() => bigint` |
| `nextUint24` | `() => T` |

#### :gear: nextUint32

| Method | Type |
| ---------- | ---------- |
| `nextUint32` | `() => bigint` |
| `nextUint32` | `() => T` |

#### :gear: nextUint128

| Method | Type |
| ---------- | ---------- |
| `nextUint128` | `() => bigint` |
| `nextUint128` | `() => T` |

#### :gear: nextUint160

| Method | Type |
| ---------- | ---------- |
| `nextUint160` | `() => bigint` |
| `nextUint160` | `() => T` |

#### :gear: nextUint256

| Method | Type |
| ---------- | ---------- |
| `nextUint256` | `() => bigint` |
| `nextUint256` | `() => T` |


## :factory: BytesBuilder
Expand Down
17 changes: 17 additions & 0 deletions src/bytes-iter/bytes-iter.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {BytesIter} from './bytes-iter'

describe('BytesIter', () => {
it('should iterate as BigInt ', () => {
const iter = BytesIter.BigInt('0xdeadbeef')
expect(iter.nextByte()).toEqual(BigInt(0xde))
expect(iter.nextByte()).toEqual(BigInt(0xad))
expect(iter.nextBytes(2)).toEqual(BigInt(0xbeef))
})

it('should iterate as String ', () => {
const iter = BytesIter.String('0xdeadbeef')
expect(iter.nextByte()).toEqual('0xde')
expect(iter.nextByte()).toEqual('0xad')
expect(iter.nextBytes(2)).toEqual('0xbeef')
})
})
44 changes: 31 additions & 13 deletions src/bytes-iter/bytes-iter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,47 @@ import {add0x} from '../utils'
* Class to iterate through bytes string by parsing individual bytes
*
* @example
* const iter = new BytesIter('0xdeadbeef')
* const iter = BytesIter.BigInt('0xdeadbeef')
* iter.nextByte() == BigInt(0xde)
* iter.nextByte() == BigInt(0xad)
* iter.nextBytes(2) == BigInt(0xbeef)
*/
export class BytesIter {
export class BytesIter<T> {
private bytes: string

constructor(bytes: string) {
private constructor(
bytes: string,
private readonly ResultType: (val: string) => T
) {
assert(isHexBytes(bytes), 'invalid bytes value')

this.bytes = bytes.slice(2) // trim 0x
}

static BigInt(bytes: string): BytesIter<bigint> {
return new BytesIter(bytes, BigInt)
}

static String(bytes: string): BytesIter<string> {
return new BytesIter(bytes, String)
}

/**
* Returns all not consumed bytes
*/
public rest(): T {
return this.ResultType(add0x(this.bytes))
}

public isEmpty(): boolean {
return this.bytes.length === 0
}

public nextByte(): bigint {
public nextByte(): T {
return this.nextBytes(1)
}

public nextBytes(n: number): bigint {
public nextBytes(n: number): T {
const cnt = n * 2

if (this.bytes.length < cnt) {
Expand All @@ -41,34 +59,34 @@ export class BytesIter {

this.bytes = this.bytes.slice(cnt)

return BigInt(add0x(bytes))
return this.ResultType(add0x(bytes))
}

public nextUint8(): bigint {
public nextUint8(): T {
return this.nextByte()
}

public nextUint16(): bigint {
public nextUint16(): T {
return this.nextBytes(2)
}

public nextUint24(): bigint {
public nextUint24(): T {
return this.nextBytes(3)
}

public nextUint32(): bigint {
public nextUint32(): T {
return this.nextBytes(4)
}

public nextUint128(): bigint {
public nextUint128(): T {
return this.nextBytes(16)
}

public nextUint160(): bigint {
public nextUint160(): T {
return this.nextBytes(20)
}

public nextUint256(): bigint {
public nextUint256(): T {
return this.nextBytes(32)
}
}
13 changes: 13 additions & 0 deletions src/utils/as-bytes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Formats `val` as 0x prefixed string with even length
* @param val
*/
export function asBytes(val: bigint): string {
const hex = val.toString(16)

if (hex.length % 2) {
return '0x0' + hex
}

return '0x' + hex
}
5 changes: 5 additions & 0 deletions src/utils/get-bytes-count.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {trim0x} from './zero-x-prefix'

export function getBytesCount(hex: string): bigint {
return BigInt(trim0x(hex).length / 2)
}
2 changes: 2 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from './zero-x-prefix'
export * from './get-bytes-count'
export * from './as-bytes'