Skip to content

Commit

Permalink
fix: port protobuf reader/writer to ts (#60)
Browse files Browse the repository at this point in the history
Ports just the parts of protobufjs we use to typescript and integrates
the changes from protobufjs/protobuf.js#1557
to have native BigInt support.
  • Loading branch information
achingbrain authored Oct 13, 2023
1 parent d8c4e6b commit d101804
Show file tree
Hide file tree
Showing 12 changed files with 1,173 additions and 93 deletions.
7 changes: 2 additions & 5 deletions packages/protons-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,10 @@
"release": "aegir release"
},
"dependencies": {
"protobufjs": "^7.0.0",
"uint8arraylist": "^2.4.3"
"uint8arraylist": "^2.4.3",
"uint8arrays": "^4.0.6"
},
"devDependencies": {
"aegir": "^41.0.4"
},
"peerDependencies": {
"uint8arraylist": "^2.3.2"
}
}
6 changes: 3 additions & 3 deletions packages/protons-runtime/src/decode.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { reader } from './utils.js'
import { createReader } from './utils/reader.js'
import type { Codec } from './codec.js'
import type { Uint8ArrayList } from 'uint8arraylist'

export function decodeMessage <T> (buf: Uint8Array | Uint8ArrayList, codec: Codec<T>): T {
const r = reader(buf instanceof Uint8Array ? buf : buf.subarray())
const reader = createReader(buf)

return codec.decode(r)
return codec.decode(reader)
}
4 changes: 2 additions & 2 deletions packages/protons-runtime/src/encode.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { writer } from './utils.js'
import { createWriter } from './utils/writer.js'
import type { Codec } from './codec.js'

export function encodeMessage <T> (message: T, codec: Codec<T>): Uint8Array {
const w = writer()
const w = createWriter()

codec.encode(message, w, {
lengthDelimited: false
Expand Down
39 changes: 20 additions & 19 deletions packages/protons-runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export {

export { enumeration } from './codecs/enum.js'
export { message } from './codecs/message.js'
export { reader, writer } from './utils.js'
export { createReader as reader } from './utils/reader.js'
export { createWriter as writer } from './utils/writer.js'
export type { Codec, EncodeOptions } from './codec.js'

export interface Writer {
Expand All @@ -30,93 +31,93 @@ export interface Writer {
/**
* Writes an unsigned 32 bit value as a varint
*/
uint32(value: number): Writer
uint32(value: number): this

/**
* Writes a signed 32 bit value as a varint`
*/
int32(value: number): Writer
int32(value: number): this

/**
* Writes a 32 bit value as a varint, zig-zag encoded
*/
sint32(value: number): Writer
sint32(value: number): this

/**
* Writes an unsigned 64 bit value as a varint
*/
uint64(value: bigint): Writer
uint64(value: bigint): this

/**
* Writes a signed 64 bit value as a varint
*/
int64(value: bigint): Writer
int64(value: bigint): this

/**
* Writes a signed 64 bit value as a varint, zig-zag encoded
*/
sint64(value: bigint): Writer
sint64(value: bigint): this

/**
* Writes a boolish value as a varint
*/
bool(value: boolean): Writer
bool(value: boolean): this

/**
* Writes an unsigned 32 bit value as fixed 32 bits
*/
fixed32(value: number): Writer
fixed32(value: number): this

/**
* Writes a signed 32 bit value as fixed 32 bits
*/
sfixed32(value: number): Writer
sfixed32(value: number): this

/**
* Writes an unsigned 64 bit value as fixed 64 bits
*/
fixed64(value: bigint): Writer
fixed64(value: bigint): this

/**
* Writes a signed 64 bit value as fixed 64 bits
*/
sfixed64(value: bigint): Writer
sfixed64(value: bigint): this

/**
* Writes a float (32 bit)
*/
float(value: number): Writer
float(value: number): this

/**
* Writes a double (64 bit float)
*/
double(value: number): Writer
double(value: number): this

/**
* Writes a sequence of bytes
*/
bytes(value: Uint8Array): Writer
bytes(value: Uint8Array): this

/**
* Writes a string
*/
string(value: string): Writer
string(value: string): this

/**
* Forks this writer's state by pushing it to a stack.
* Calling {@link Writer#reset|reset} or {@link Writer#ldelim|ldelim} resets the writer to the previous state.
*/
fork(): Writer
fork(): this

/**
* Resets this instance to the last state.
*/
reset(): Writer
reset(): this

/**
* Resets to the last state and appends the fork state's current write length as a varint followed by its operations.
*/
ldelim(): Writer
ldelim(): this

/**
* Finishes the write operation
Expand Down
63 changes: 0 additions & 63 deletions packages/protons-runtime/src/utils.ts

This file was deleted.

109 changes: 109 additions & 0 deletions packages/protons-runtime/src/utils/float.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
const f32 = new Float32Array([-0])
const f8b = new Uint8Array(f32.buffer)

/**
* Writes a 32 bit float to a buffer using little endian byte order
*/
export function writeFloatLE (val: number, buf: Uint8Array, pos: number): void {
f32[0] = val
buf[pos] = f8b[0]
buf[pos + 1] = f8b[1]
buf[pos + 2] = f8b[2]
buf[pos + 3] = f8b[3]
}

/**
* Writes a 32 bit float to a buffer using big endian byte order
*/
export function writeFloatBE (val: number, buf: Uint8Array, pos: number): void {
f32[0] = val
buf[pos] = f8b[3]
buf[pos + 1] = f8b[2]
buf[pos + 2] = f8b[1]
buf[pos + 3] = f8b[0]
}

/**
* Reads a 32 bit float from a buffer using little endian byte order
*/
export function readFloatLE (buf: Uint8Array, pos: number): number {
f8b[0] = buf[pos]
f8b[1] = buf[pos + 1]
f8b[2] = buf[pos + 2]
f8b[3] = buf[pos + 3]
return f32[0]
}

/**
* Reads a 32 bit float from a buffer using big endian byte order
*/
export function readFloatBE (buf: Uint8Array, pos: number): number {
f8b[3] = buf[pos]
f8b[2] = buf[pos + 1]
f8b[1] = buf[pos + 2]
f8b[0] = buf[pos + 3]
return f32[0]
}

const f64 = new Float64Array([-0])
const d8b = new Uint8Array(f64.buffer)

/**
* Writes a 64 bit double to a buffer using little endian byte order
*/
export function writeDoubleLE (val: number, buf: Uint8Array, pos: number): void {
f64[0] = val
buf[pos] = d8b[0]
buf[pos + 1] = d8b[1]
buf[pos + 2] = d8b[2]
buf[pos + 3] = d8b[3]
buf[pos + 4] = d8b[4]
buf[pos + 5] = d8b[5]
buf[pos + 6] = d8b[6]
buf[pos + 7] = d8b[7]
}

/**
* Writes a 64 bit double to a buffer using big endian byte order
*/
export function writeDoubleBE (val: number, buf: Uint8Array, pos: number): void {
f64[0] = val
buf[pos] = d8b[7]
buf[pos + 1] = d8b[6]
buf[pos + 2] = d8b[5]
buf[pos + 3] = d8b[4]
buf[pos + 4] = d8b[3]
buf[pos + 5] = d8b[2]
buf[pos + 6] = d8b[1]
buf[pos + 7] = d8b[0]
}

/**
* Reads a 64 bit double from a buffer using little endian byte order
*/
export function readDoubleLE (buf: Uint8Array, pos: number): number {
d8b[0] = buf[pos]
d8b[1] = buf[pos + 1]
d8b[2] = buf[pos + 2]
d8b[3] = buf[pos + 3]
d8b[4] = buf[pos + 4]
d8b[5] = buf[pos + 5]
d8b[6] = buf[pos + 6]
d8b[7] = buf[pos + 7]
return f64[0]
}

/**
* Reads a 64 bit double from a buffer using big endian byte order
*/
export function readDoubleBE (buf: Uint8Array, pos: number): number {
d8b[7] = buf[pos]
d8b[6] = buf[pos + 1]
d8b[5] = buf[pos + 2]
d8b[4] = buf[pos + 3]
d8b[3] = buf[pos + 4]
d8b[2] = buf[pos + 5]
d8b[1] = buf[pos + 6]
d8b[0] = buf[pos + 7]
return f64[0]
}
Loading

0 comments on commit d101804

Please sign in to comment.