-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
eea9622
commit 62fc246
Showing
9 changed files
with
495 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
packages/massa-web3/src/experimental/basicElements/serializers/number/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * as U8 from './u8' | ||
export * as U16 from './u16' | ||
export * as U32 from './u32' | ||
export * as U64 from './u64' |
69 changes: 69 additions & 0 deletions
69
packages/massa-web3/src/experimental/basicElements/serializers/number/integers.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { U16, U32, U64, U8 } from '..' | ||
import { FIRST, ONE, ZERO } from '../../../utils' | ||
|
||
function mustBeValidUnsigned(sizeInBits: number, value: bigint): void { | ||
if (value < BigInt(ZERO)) { | ||
throw new Error("negative value can't be serialized as unsigned integer.") | ||
} | ||
if (value >= BigInt(ONE) << BigInt(sizeInBits)) { | ||
throw new Error(`value ${value} is too large for an U${sizeInBits}.`) | ||
} | ||
} | ||
|
||
export function unsignedToByte(sizeInBits: number, value: bigint): Uint8Array { | ||
mustBeValidUnsigned(sizeInBits, value) | ||
const buffer = new ArrayBuffer(sizeInBits / U8.SIZE_BIT) | ||
const view = new DataView(buffer) | ||
switch (sizeInBits) { | ||
case U8.SIZE_BIT: | ||
view.setUint8(FIRST, Number(value)) | ||
break | ||
case U16.SIZE_BIT: | ||
view.setUint16(FIRST, Number(value), true) | ||
break | ||
case U32.SIZE_BIT: | ||
view.setUint32(FIRST, Number(value), true) | ||
break | ||
case U64.SIZE_BIT: | ||
view.setBigUint64(FIRST, value, true) | ||
break | ||
default: | ||
throw new Error(`unsupported U${sizeInBits} serialization.`) | ||
} | ||
return new Uint8Array(view.buffer) | ||
} | ||
|
||
export function unsignedFromByte( | ||
sizeInBits: number, | ||
bytes: Uint8Array, | ||
index = FIRST | ||
): bigint { | ||
if (bytes.length < index + sizeInBits / U8.SIZE_BIT) { | ||
throw new Error('not enough bytes to read the value.') | ||
} | ||
const view = new DataView(bytes.buffer) | ||
switch (sizeInBits) { | ||
case U8.SIZE_BIT: | ||
return BigInt(view.getUint8(index)) | ||
case U16.SIZE_BIT: | ||
return BigInt(view.getUint16(index, true)) | ||
case U32.SIZE_BIT: | ||
return BigInt(view.getUint32(index, true)) | ||
case U64.SIZE_BIT: | ||
return view.getBigUint64(index, true) | ||
default: | ||
throw new Error(`unsupported U${sizeInBits} deserialization`) | ||
} | ||
} | ||
|
||
export function numberToUnsigned( | ||
sizeInBits: number, | ||
value: number | bigint | ||
): bigint { | ||
if (typeof value === 'number' && !Number.isSafeInteger(value)) { | ||
throw new Error(`value ${value} is not a safe integer.`) | ||
} | ||
const int = BigInt(value) | ||
mustBeValidUnsigned(sizeInBits, int) | ||
return int | ||
} |
59 changes: 59 additions & 0 deletions
59
packages/massa-web3/src/experimental/basicElements/serializers/number/u16.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { U8 } from '.' | ||
import { ONE } from '../../../utils' | ||
import { numberToUnsigned, unsignedFromByte, unsignedToByte } from './integers' | ||
|
||
export type U16 = bigint | ||
|
||
export const SIZE_BYTE = 2 | ||
export const SIZE_BIT = SIZE_BYTE * U8.SIZE_BIT | ||
export const MAX = (BigInt(ONE) << BigInt(SIZE_BIT)) - BigInt(ONE) | ||
|
||
/** | ||
* Converts an U16 value to bytes | ||
* | ||
* @param value - The number to convert | ||
* @returns The bytes representation of the number | ||
* @throws if the value is negative or too large for U16 | ||
*/ | ||
export function toBytes(value: U16): Uint8Array { | ||
return unsignedToByte(SIZE_BIT, value) | ||
} | ||
|
||
/** | ||
* Converts bytes to an U16 value | ||
* | ||
* @remarks | ||
* Silently ignores bytes that are not needed to represent the U8 value. | ||
* | ||
* @param bytes - The bytes to convert | ||
* @returns The U16 representation of the bytes | ||
*/ | ||
export function fromBytes(bytes: Uint8Array): U16 { | ||
return unsignedFromByte(SIZE_BIT, bytes) | ||
} | ||
|
||
/** | ||
* Converts an U16 value to a number | ||
* @param buffer - The buffer to read from | ||
* @param offset - The optional offset in the buffer at which to start reading the U16 value (default: 0) | ||
* @returns The U16 representation of the bytes | ||
*/ | ||
export function fromBuffer( | ||
buffer: Uint8Array, | ||
offset: number | ||
): { value: U16; offset: number } { | ||
const value = unsignedFromByte(SIZE_BIT, buffer, offset) | ||
offset += SIZE_BYTE | ||
return { value, offset } | ||
} | ||
|
||
/** | ||
* Converts a number to an U16 value | ||
* | ||
* @param value - The number to convert | ||
* @returns The U16 representation of the number | ||
* @throws if the value is not a safe integer, negative or too large for U16 | ||
*/ | ||
export function fromNumber(value: number): U16 { | ||
return numberToUnsigned(SIZE_BIT, value) | ||
} |
59 changes: 59 additions & 0 deletions
59
packages/massa-web3/src/experimental/basicElements/serializers/number/u32.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { U8 } from '.' | ||
import { ONE } from '../../../utils' | ||
import { numberToUnsigned, unsignedFromByte, unsignedToByte } from './integers' | ||
|
||
export type U32 = bigint | ||
|
||
export const SIZE_BYTE = 4 | ||
export const SIZE_BIT = SIZE_BYTE * U8.SIZE_BIT | ||
export const MAX = (BigInt(ONE) << BigInt(SIZE_BIT)) - BigInt(ONE) | ||
|
||
/** | ||
* Converts an U32 value to bytes | ||
* | ||
* @param value - The number to convert | ||
* @returns The bytes representation of the number | ||
* @throws if the value is negative or too large for U32 | ||
*/ | ||
export function toBytes(value: U32): Uint8Array { | ||
return unsignedToByte(SIZE_BIT, value) | ||
} | ||
|
||
/** | ||
* Converts bytes to an U32 value | ||
* | ||
* @remarks | ||
* Silently ignores bytes that are not needed to represent the U8 value. | ||
* | ||
* @param bytes - The bytes to convert | ||
* @returns The U32 representation of the bytes | ||
*/ | ||
export function fromBytes(bytes: Uint8Array): U32 { | ||
return unsignedFromByte(SIZE_BIT, bytes) | ||
} | ||
|
||
/** | ||
* Converts an U32 value to a number | ||
* @param buffer - The buffer to read from | ||
* @param offset - The optional offset in the buffer at which to start reading the U32 value (default: 0) | ||
* @returns The U32 representation of the bytes | ||
*/ | ||
export function fromBuffer( | ||
buffer: Uint8Array, | ||
offset: number | ||
): { value: U32; offset: number } { | ||
const value = unsignedFromByte(SIZE_BIT, buffer, offset) | ||
offset += SIZE_BYTE | ||
return { value, offset } | ||
} | ||
|
||
/** | ||
* Converts a number to an U32 value | ||
* | ||
* @param value - The number to convert | ||
* @returns The U32 representation of the number | ||
* @throws if the value is not a safe integer, negative or too large for U32 | ||
*/ | ||
export function fromNumber(value: number): U32 { | ||
return numberToUnsigned(SIZE_BIT, value) | ||
} |
59 changes: 59 additions & 0 deletions
59
packages/massa-web3/src/experimental/basicElements/serializers/number/u64.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { U8 } from '.' | ||
import { ONE } from '../../../utils' | ||
import { numberToUnsigned, unsignedFromByte, unsignedToByte } from './integers' | ||
|
||
export type U64 = bigint | ||
|
||
export const SIZE_BYTE = 8 | ||
export const SIZE_BIT = SIZE_BYTE * U8.SIZE_BIT | ||
export const MAX = (BigInt(ONE) << BigInt(SIZE_BIT)) - BigInt(ONE) | ||
|
||
/** | ||
* Converts an U64 value to bytes | ||
* | ||
* @param value - The number to convert | ||
* @returns The bytes representation of the number | ||
* @throws if the value is negative or too large for U64 | ||
*/ | ||
export function toBytes(value: U64): Uint8Array { | ||
return unsignedToByte(SIZE_BIT, value) | ||
} | ||
|
||
/** | ||
* Converts bytes to an U64 value | ||
* | ||
* @remarks | ||
* Silently ignores bytes that are not needed to represent the U8 value. | ||
* | ||
* @param bytes - The bytes to convert | ||
* @returns The U64 representation of the bytes | ||
*/ | ||
export function fromBytes(bytes: Uint8Array): U64 { | ||
return unsignedFromByte(SIZE_BIT, bytes) | ||
} | ||
|
||
/** | ||
* Converts an U64 value to a number | ||
* @param buffer - The buffer to read from | ||
* @param offset - The optional offset in the buffer at which to start reading the U64 value (default: 0) | ||
* @returns The U64 representation of the bytes | ||
*/ | ||
export function fromBuffer( | ||
buffer: Uint8Array, | ||
offset: number | ||
): { value: U64; offset: number } { | ||
const value = unsignedFromByte(SIZE_BIT, buffer, offset) | ||
offset += SIZE_BYTE | ||
return { value, offset } | ||
} | ||
|
||
/** | ||
* Converts a number to an U64 value | ||
* | ||
* @param value - The number to convert | ||
* @returns The U64 representation of the number | ||
* @throws if the value is not a safe integer, negative or too large for U64 | ||
*/ | ||
export function fromNumber(value: number | bigint): U64 { | ||
return numberToUnsigned(SIZE_BIT, value) | ||
} |
58 changes: 58 additions & 0 deletions
58
packages/massa-web3/src/experimental/basicElements/serializers/number/u8.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { ONE } from '../../../utils' | ||
import { numberToUnsigned, unsignedFromByte, unsignedToByte } from './integers' | ||
|
||
export type U8 = bigint | ||
|
||
export const SIZE_BYTE = 1 | ||
export const SIZE_BIT = 8 | ||
export const MAX = (BigInt(ONE) << BigInt(SIZE_BIT)) - BigInt(ONE) | ||
|
||
/** | ||
* Converts an U8 value to bytes | ||
* | ||
* @param value - The number to convert | ||
* @returns The bytes representation of the number | ||
* @throws if the value is negative or too large for U8 | ||
*/ | ||
export function toBytes(value: U8): Uint8Array { | ||
return unsignedToByte(SIZE_BIT, value) | ||
} | ||
|
||
/** | ||
* Converts bytes to an U8 value | ||
* | ||
* @remarks | ||
* Silently ignores bytes that are not needed to represent the U8 value. | ||
* | ||
* @param bytes - The bytes to convert | ||
* @returns The U8 representation of the bytes | ||
*/ | ||
export function fromBytes(bytes: Uint8Array): U8 { | ||
return unsignedFromByte(SIZE_BIT, bytes) | ||
} | ||
|
||
/** | ||
* Converts an U8 value to a number | ||
* @param buffer - The buffer to read from | ||
* @param offset - The optional offset in the buffer at which to start reading the U8 value (default: 0) | ||
* @returns The U8 representation of the bytes | ||
*/ | ||
export function fromBuffer( | ||
buffer: Uint8Array, | ||
offset: number | ||
): { value: U8; offset: number } { | ||
const value = unsignedFromByte(SIZE_BIT, buffer, offset) | ||
offset += SIZE_BYTE | ||
return { value, offset } | ||
} | ||
|
||
/** | ||
* Converts a number to an U8 value | ||
* | ||
* @param value - The number to convert | ||
* @returns The U8 representation of the number | ||
* @throws if the value is not a safe integer, negative or too large for U8 | ||
*/ | ||
export function fromNumber(value: number): U8 { | ||
return numberToUnsigned(SIZE_BIT, value) | ||
} |
Oops, something went wrong.
62fc246
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coverage report for experimental massa-web3
Test suite run success
121 tests passing in 13 suites.
Report generated by π§ͺjest coverage report action from 62fc246
62fc246
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coverage report for experimental massa-web3
Test suite run success
121 tests passing in 13 suites.
Report generated by π§ͺjest coverage report action from 62fc246