-
Notifications
You must be signed in to change notification settings - Fork 0
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
0 parents
commit dd4afb3
Showing
30 changed files
with
2,692 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
name: Test | ||
|
||
on: [push, pull_request] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/cache@v3 | ||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: 20 | ||
- run: npm install | ||
- run: npm run integration |
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 @@ | ||
.history | ||
coverage | ||
.vscode | ||
*.tgz |
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,6 @@ | ||
.history | ||
coverage | ||
.vscode | ||
.github | ||
*.tgz | ||
test |
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,9 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright © 2023 Martin Heidegger | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
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,78 @@ | ||
# protobuf-varint | ||
|
||
⚡️ | ||
|
||
Fast encoding and decoding for all variable [protobuf-style varint bytes](https://developers.google.com/protocol-buffers/docs/encoding#varints) and also decode them. | ||
|
||
- Supports 64bit values using `longfn` or `long.js` compatible objects. | ||
- Protocol-buffer compatible for **all** edge cases | ||
- Codecs for all types: `int32`, `sint32`, `uint32`, `int64`, `sint64` and `uint64` | ||
- Pure JavaScript | ||
- No dependencies | ||
- TypeScript declaration files 😉 | ||
|
||
## Usage | ||
|
||
### Encoding | ||
|
||
```js | ||
import { uint64 } from 'protobuf-varint' | ||
import { fromBigInt } from 'longfn' | ||
|
||
// You can use numbers for the whole uint64 range with the longfn | ||
// lib to be easily created from a variety of formats | ||
const long = fromBigInt(0xffffffffffffffffn) | ||
|
||
const fixedEncoder = uint64.fixedEncoder(long) | ||
const buffer = new Uint8Array( | ||
fixedEncoder.bytes, // The fixedEncoder containst the size needed to write the var-int | ||
) | ||
fixedEncoder.encode(long, buffer, 0) // Profit! | ||
``` | ||
|
||
### Decoding | ||
|
||
```js | ||
// Use a operation object to reduce memory consumption | ||
const target = { low: 0, high: 0, unsigned: false } | ||
uint64.decode(buffer, 0, target) | ||
// `target` now contains the value from the buffer! | ||
|
||
uint64.decode.bytes // amount of bytes that were previously read | ||
``` | ||
|
||
### Backwards Compatibility | ||
|
||
Other encoding systems tend to use the `encode` and `encodeLength` functions | ||
to encode content. This is discouraged because there is nearly no use-case for | ||
`encode` on its own. `fixedEncoder` removes the need for a set of preconditions | ||
checks that would need to be done twice, still you can use `encode` and `encodeLength` | ||
as with others. | ||
|
||
```js | ||
import { encode, encodeLength } from 'protobuf-varint/sint32' | ||
|
||
// Note this is deprecated! Use `fixedEncoder`! | ||
|
||
const int32 = -1311313 | ||
const buffer = new Uint8Array(encodeLength(int32)) | ||
encode(int32, buffer, 0) | ||
``` | ||
|
||
### Flexible Partial Access | ||
|
||
Depending on your usage you can choose different variants matching your needs. | ||
|
||
```js | ||
import { uint64 } from 'protobuf-varint' | ||
import * as int32 from 'protobuf-varint/int32' | ||
import { fixedEncoder } from 'protobuf-varint/sint64' | ||
import { decode as decodeSInt32 } from 'protobuf-varint/sint32' | ||
import { decode as decodeSInt64 } from 'protobuf-varint/sint64' | ||
import { codecs } from 'protobuf-varint' | ||
codecs.int64 | ||
``` | ||
|
||
# License | ||
|
||
[MIT](./LICENSE) |
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,15 @@ | ||
import * as int32 from './int32.mjs' | ||
import * as int64 from './int64.mjs' | ||
import * as sint32 from './sint32.mjs' | ||
import * as sint64 from './sint64.mjs' | ||
import * as uint32 from './uint32.mjs' | ||
import * as uint64 from './uint64.mjs' | ||
|
||
export const codecs: Readonly<{ | ||
int32: typeof int32 | ||
int64: typeof int64 | ||
sint32: typeof sint32 | ||
sint64: typeof sint64 | ||
uint32: typeof uint32 | ||
uint64: typeof uint64 | ||
}> |
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,14 @@ | ||
import * as int32 from './int32.mjs' | ||
import * as uint32 from './uint32.mjs' | ||
import * as sint32 from './sint32.mjs' | ||
import * as int64 from './int64.mjs' | ||
import * as uint64 from './uint64.mjs' | ||
import * as sint64 from './sint64.mjs' | ||
export const codecs = Object.freeze({ | ||
int32, | ||
uint32, | ||
sint32, | ||
int64, | ||
uint64, | ||
sint64, | ||
}) |
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,9 @@ | ||
export const NUMBER_UNSAFE = 'Numbers are unsafe, use BigInt, Long or Bytes' | ||
export const NUMBER_NEGATIVE = 'Numbers need to be positive (>= 0)' | ||
export const NUMBER_FLOATING_POINT = 'Number needs to be an integer' | ||
export const UINT32_TOO_LARGE = 'Numbers need to be smaller or equal 0xffffffff' | ||
export const INT32_TOO_LARGE = 'Numbers need to be smaller or equal 0x7fffffff' | ||
export const INT32_TOO_SMALL = 'Numbers need to be bigger or equal -0x80000000' | ||
export const INVALID_LONG = 'Input not coerceable to a long number' | ||
export const INVALID_NUMBER = 'Input not coerceable to a number' | ||
export const NAN = 'Input is NaN' |
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,9 @@ | ||
export const NUMBER_UNSAFE = 'Numbers are unsafe, use BigInt, Long or Bytes' | ||
export const NUMBER_NEGATIVE = 'Numbers need to be positive (>= 0)' | ||
export const NUMBER_FLOATING_POINT = 'Number needs to be an integer' | ||
export const UINT32_TOO_LARGE = 'Numbers need to be smaller or equal 0xffffffff' | ||
export const INT32_TOO_LARGE = 'Numbers need to be smaller or equal 0x7fffffff' | ||
export const INT32_TOO_SMALL = 'Numbers need to be bigger or equal -0x80000000' | ||
export const INVALID_LONG = 'Input not coerceable to a long number' | ||
export const INVALID_NUMBER = 'Input not coerceable to a number' | ||
export const NAN = 'Input is NaN' |
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,9 @@ | ||
export * as int32 from './int32.mjs' | ||
export * as int64 from './int64.mjs' | ||
export * as sint32 from './sint32.mjs' | ||
export * as sint64 from './sint64.mjs' | ||
export * as uint32 from './uint32.mjs' | ||
export * as uint64 from './uint64.mjs' | ||
export * as errors from './errors.mjs' | ||
export { codecs } from './codecs.mjs' | ||
export * from './types.mjs' |
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,9 @@ | ||
export * as int32 from './int32.mjs' | ||
export * as int64 from './int64.mjs' | ||
export * as sint32 from './sint32.mjs' | ||
export * as sint64 from './sint64.mjs' | ||
export * as uint32 from './uint32.mjs' | ||
export * as uint64 from './uint64.mjs' | ||
export * as errors from './errors.mjs' | ||
export { codecs } from './codecs.mjs' | ||
export * from './types.mjs' |
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,16 @@ | ||
import type { | ||
NumberDecode, | ||
NumberEncode, | ||
NumberEncodeLength, | ||
NumberFixedEncode, | ||
Validator, | ||
} from './types.mjs' | ||
|
||
export const decode: NumberDecode | ||
export const encode: NumberEncode | ||
export const encodeLength: NumberEncodeLength | ||
export const fixedEncoder: NumberFixedEncode | ||
export const name = 'int32' | ||
export const validate: Validator<string> | ||
export const MIN_VALUE = -0b10000000000000000000000000000000 | ||
export const MAX_VALUE = 0b01111111111111111111111111111111 |
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,92 @@ | ||
import { | ||
INT32_TOO_LARGE, | ||
INT32_TOO_SMALL, | ||
NAN, | ||
INVALID_NUMBER, | ||
NUMBER_FLOATING_POINT, | ||
} from './errors.mjs' | ||
import { fixedEncoders as fixedUint, B1, B2, B3, B4 } from './uint32.mjs' | ||
|
||
export const name = 'int32' | ||
|
||
export const MIN_VALUE = -0b10000000000000000000000000000000 | ||
export const MAX_VALUE = 0b01111111111111111111111111111111 | ||
|
||
const MSB = 0b10000000 | ||
const REST = 0b01111111 | ||
const POS = 0b0111 | ||
const NEG = 0b1000 | ||
|
||
export function decode(bytes, offset = 0) { | ||
let b = bytes[offset] | ||
if (!(b & MSB)) { | ||
decode.bytes = 1 | ||
return b | ||
} | ||
let result = b & REST | ||
b = bytes[offset + 1] | ||
if (!(b & MSB)) { | ||
decode.bytes = 2 | ||
return result | (b << 7) | ||
} | ||
result |= (b & REST) << 7 | ||
b = bytes[offset + 2] | ||
if (!(b & MSB)) { | ||
decode.bytes = 3 | ||
return result | (b << 14) | ||
} | ||
result |= (b & REST) << 14 | ||
b = bytes[offset + 3] | ||
if (!(b & MSB)) { | ||
decode.bytes = 4 | ||
return result | (b << 21) | ||
} | ||
result |= (b & REST) << 21 | ||
b = bytes[offset + 4] | ||
decode.bytes = 5 | ||
return result + (b & POS) * 0x10000000 - (b & NEG) * 0x10000000 | ||
} | ||
decode.bytes = 1 | ||
|
||
export function encode(int32, target, offset) { | ||
const { bytes, encode: fixEncode } = fixedEncoder(int32) | ||
encode.bytes = bytes | ||
return fixEncode(int32, target, offset) | ||
} | ||
encode.bytes = 1 | ||
|
||
export function encodeLength(int32) { | ||
return fixedEncoder(int32).bytes | ||
} | ||
|
||
const NE = 0x100000000 | ||
|
||
const [p1, p2, p3, p4, p5] = fixedUint | ||
const p5encode = p5.encode | ||
const neg = Object.freeze({ | ||
bytes: 5, | ||
encode(int, out, offset) { | ||
return p5encode(NE + int, out, offset) | ||
}, | ||
}) | ||
|
||
export const fixedEncoder = (int) => | ||
int < 0 | ||
? neg | ||
: int & B4 | ||
? p5 | ||
: int & B3 | ||
? p4 | ||
: int & B2 | ||
? p3 | ||
: int & B1 | ||
? p2 | ||
: p1 | ||
|
||
export function validate(input) { | ||
if (typeof input !== 'number') return INVALID_NUMBER | ||
if (isNaN(input)) return NAN | ||
if (input < MIN_VALUE) return INT32_TOO_SMALL | ||
if (input > MAX_VALUE) return INT32_TOO_LARGE | ||
if (input !== (input | 0)) return NUMBER_FLOATING_POINT | ||
} |
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,14 @@ | ||
import type { | ||
SLongDecode, | ||
SLongEncode, | ||
SLongEncodeLength, | ||
SLongFixedEncode, | ||
Validator, | ||
} from './types.mjs' | ||
|
||
export const decode: SLongDecode | ||
export const encode: SLongEncode | ||
export const encodeLength: SLongEncodeLength | ||
export const fixedEncoder: SLongFixedEncode | ||
export const name = 'int64' | ||
export const validate: Validator<string> |
Oops, something went wrong.