Skip to content

Commit

Permalink
Developed typia.protobuf.encode<T>() function.
Browse files Browse the repository at this point in the history
However, test programs are not yet.
  • Loading branch information
samchon committed Aug 18, 2023
1 parent 5f0a6d6 commit e2f2ff1
Show file tree
Hide file tree
Showing 30 changed files with 1,649 additions and 1,038 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typia",
"version": "5.0.0-dev.20230814",
"version": "5.0.0-dev.20230818",
"description": "Superfast runtime validators with only one line",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down
4 changes: 2 additions & 2 deletions packages/typescript-json/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typescript-json",
"version": "5.0.0-dev.20230814",
"version": "5.0.0-dev.20230818",
"description": "Superfast runtime validators with only one line",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -68,7 +68,7 @@
},
"homepage": "https://typia.io",
"dependencies": {
"typia": "5.0.0-dev.20230814"
"typia": "5.0.0-dev.20230818"
},
"peerDependencies": {
"typescript": ">= 4.7.4"
Expand Down
20 changes: 20 additions & 0 deletions src/factories/ExpressionFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,24 @@ export namespace ExpressionFactory {
ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
y,
);

export const currying =
(target: ts.Expression) => (parameters: ts.Expression[]) => {
if (parameters.length === 0)
return ts.factory.createCallExpression(
target,
undefined,
undefined,
);
let prev: ts.CallExpression = ts.factory.createCallExpression(
target,
undefined,
[parameters[0]!],
);
for (const param of parameters.slice(1))
prev = ts.factory.createCallExpression(prev, undefined, [
param,
]);
return prev;
};
}
32 changes: 32 additions & 0 deletions src/factories/StatementFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,40 @@ export namespace StatementFactory {
),
);

export const entry = (key: string) => (value: string) =>
ts.factory.createVariableDeclarationList(
[
ts.factory.createVariableDeclaration(
ts.factory.createArrayBindingPattern([
ts.factory.createBindingElement(
undefined,
undefined,
ts.factory.createIdentifier(key),
undefined,
),
ts.factory.createBindingElement(
undefined,
undefined,
ts.factory.createIdentifier(value),
undefined,
),
]),
undefined,
undefined,
undefined,
),
],
ts.NodeFlags.Const,
);

export const transpile = (script: string) =>
ts.factory.createExpressionStatement(
ts.factory.createIdentifier(ts.transpile(script)),
);

export const block = (expression: ts.Expression) =>
ts.factory.createBlock(
[ts.factory.createExpressionStatement(expression)],
true,
);
}
189 changes: 189 additions & 0 deletions src/functional/$ProtobufReader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import { ProtobufWire } from "../programmers/helpers/ProtobufWire";

export class $ProtobufReader {
/**
* Read buffer
*/
private buf: Uint8Array;

/**
* Read buffer pointer.
*/
private ptr: number;

/**
* DataView for buffer.
*/
private view: DataView;

public constructor(buf: Uint8Array) {
this.buf = buf;
this.ptr = 0;
this.view = new DataView(buf.buffer);
}

// public reset(buf: Uint8Array): void {
// this.buf = buf;
// this.ptr = 0;
// this.view = new DataView(buf.buffer);
// }

public uint32(): number {
return this.varint32();
}

public int32(): number {
return this.varint32();
}

public sint32(): number {
const value: number = this.varint32();
return (value >>> 1) ^ -(value & 1);
}

public uint64(): bigint {
return this.varint64();
}

public int64(): bigint {
return this.varint64();
}

public sint64(): bigint {
const value = this.varint64();
return (value >> N01) ^ -(value & N01);
}

public bool(): boolean {
return this.varint32() !== 0;
}

public float(): number {
const value: number = this.view.getFloat32(this.ptr, true);
this.ptr += 4;
return value;
}

public double(): number {
const value: number = this.view.getFloat64(this.ptr, true);
this.ptr += 8;
return value;
}

public bytes(): Uint8Array {
const length: number = this.uint32();
return this.buf.subarray(this.ptr, (this.ptr += length));
}

public string(): string {
return utf8.decode(this.bytes());
}

public skip(length: number): void {
if (length === 0) while (this.u8() & 0x80);
else this.ptr += length;
}

public skipType(wireType: ProtobufWire): void {
switch (wireType) {
case ProtobufWire.VARIANT:
this.skip(0);
break;
case ProtobufWire.I64:
this.skip(8);
break;
case ProtobufWire.LEN:
this.skip(this.uint32());
break;
case ProtobufWire.START_GROUP:
while (
(wireType = this.uint32() & 0x07) !== ProtobufWire.END_GROUP
)
this.skipType(wireType);
break;
case ProtobufWire.I32:
this.skip(4);
break;
default:
throw new Error("Invalid wire type " + wireType.toString());
}
}

private varint32(): number {
let loaded: number;
let value: number;

value = (loaded = this.u8()) & 0x7f;
if (loaded < 0x80) return value;

value |= ((loaded = this.u8()) & 0x7f) << 7;
if (loaded < 0x80) return value;

value |= ((loaded = this.u8()) & 0x7f) << 14;
if (loaded < 0x80) return value;

value |= ((loaded = this.u8()) & 0x7f) << 21;
if (loaded < 0x80) return value;

value |= ((loaded = this.u8()) & 0xf) << 28;
if (loaded < 0x80) return value;

// increment position until there is no continuation bit or until we read 10 bytes
if (this.u8() < 0x80) return value;
if (this.u8() < 0x80) return value;
if (this.u8() < 0x80) return value;
if (this.u8() < 0x80) return value;
if (this.u8() < 0x80) return value;

return value;
}

private varint64(): bigint {
let loaded: bigint;
let value: bigint;

value = (loaded = this.u8n()) & N7F;
if (loaded < N80) return value;

value |= ((loaded = this.u8n()) & N7F) << BigInt(7);
if (loaded < N80) return value;

value |= ((loaded = this.u8n()) & N7F) << BigInt(14);
if (loaded < N80) return value;

value |= ((loaded = this.u8n()) & N7F) << BigInt(21);
if (loaded < N80) return value;

value |= ((loaded = this.u8n()) & N7F) << BigInt(28);
if (loaded < N80) return value;

value |= ((loaded = this.u8n()) & N7F) << BigInt(35);
if (loaded < N80) return value;

value |= ((loaded = this.u8n()) & N7F) << BigInt(42);
if (loaded < N80) return value;

value |= ((loaded = this.u8n()) & N7F) << BigInt(49);
if (loaded < N80) return value;

value |= ((loaded = this.u8n()) & N7F) << BigInt(56);
if (loaded < N80) return value;

value |= (this.u8n() & N01) << BigInt(63);

return value;
}

private u8(): number {
return this.view.getUint8(this.ptr++);
}

private u8n(): bigint {
return BigInt(this.u8());
}
}

const utf8 = new TextDecoder();
const N01 = BigInt(0x01);
const N7F = BigInt(0x7f);
const N80 = BigInt(0x80);
Loading

0 comments on commit e2f2ff1

Please sign in to comment.