- Migrated all pages from Next.js to Astro - Added PDPA-compliant Privacy Policy (Thai) - Added PDPA-compliant Terms & Conditions (Thai) - Added Cookie Policy with disclosure (Thai) - Implemented cookie consent banner (client-side) - Integrated Umami Analytics placeholder - Blog system with 3 posts - Optimized Docker configuration for production - Static site build (184KB, 11 pages) - Ready for Easypanel deployment Backup: /Users/kunthawatgreethong/Gitea/dealplustech-backup-nextjs-20260309.tar.gz
151 lines
4.0 KiB
JavaScript
151 lines
4.0 KiB
JavaScript
import { ProtoError } from "../../errors.js";
|
|
import { VARINT, FIXED_64, LENGTH_DELIMITED, FIXED_32 } from "./util.js";
|
|
class MessageReader {
|
|
#array;
|
|
#view;
|
|
#pos;
|
|
constructor(array) {
|
|
this.#array = array;
|
|
this.#view = new DataView(array.buffer, array.byteOffset, array.byteLength);
|
|
this.#pos = 0;
|
|
}
|
|
varint() {
|
|
let value = 0;
|
|
for (let shift = 0;; shift += 7) {
|
|
const byte = this.#array[this.#pos++];
|
|
value |= (byte & 0x7f) << shift;
|
|
if (!(byte & 0x80)) {
|
|
break;
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
varintBig() {
|
|
let value = 0n;
|
|
for (let shift = 0n;; shift += 7n) {
|
|
const byte = this.#array[this.#pos++];
|
|
value |= BigInt(byte & 0x7f) << shift;
|
|
if (!(byte & 0x80)) {
|
|
break;
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
bytes(length) {
|
|
const array = new Uint8Array(this.#array.buffer, this.#array.byteOffset + this.#pos, length);
|
|
this.#pos += length;
|
|
return array;
|
|
}
|
|
double() {
|
|
const value = this.#view.getFloat64(this.#pos, true);
|
|
this.#pos += 8;
|
|
return value;
|
|
}
|
|
skipVarint() {
|
|
for (;;) {
|
|
const byte = this.#array[this.#pos++];
|
|
if (!(byte & 0x80)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
skip(count) {
|
|
this.#pos += count;
|
|
}
|
|
eof() {
|
|
return this.#pos >= this.#array.byteLength;
|
|
}
|
|
}
|
|
export class FieldReader {
|
|
#reader;
|
|
#wireType;
|
|
constructor(reader) {
|
|
this.#reader = reader;
|
|
this.#wireType = -1;
|
|
}
|
|
setup(wireType) {
|
|
this.#wireType = wireType;
|
|
}
|
|
#expect(expectedWireType) {
|
|
if (this.#wireType !== expectedWireType) {
|
|
throw new ProtoError(`Expected wire type ${expectedWireType}, got ${this.#wireType}`);
|
|
}
|
|
this.#wireType = -1;
|
|
}
|
|
bytes() {
|
|
this.#expect(LENGTH_DELIMITED);
|
|
const length = this.#reader.varint();
|
|
return this.#reader.bytes(length);
|
|
}
|
|
string() {
|
|
return new TextDecoder().decode(this.bytes());
|
|
}
|
|
message(def) {
|
|
return readProtobufMessage(this.bytes(), def);
|
|
}
|
|
int32() {
|
|
this.#expect(VARINT);
|
|
return this.#reader.varint();
|
|
}
|
|
uint32() {
|
|
return this.int32();
|
|
}
|
|
bool() {
|
|
return this.int32() !== 0;
|
|
}
|
|
uint64() {
|
|
this.#expect(VARINT);
|
|
return this.#reader.varintBig();
|
|
}
|
|
sint64() {
|
|
const value = this.uint64();
|
|
return (value >> 1n) ^ (-(value & 1n));
|
|
}
|
|
double() {
|
|
this.#expect(FIXED_64);
|
|
return this.#reader.double();
|
|
}
|
|
maybeSkip() {
|
|
if (this.#wireType < 0) {
|
|
return;
|
|
}
|
|
else if (this.#wireType === VARINT) {
|
|
this.#reader.skipVarint();
|
|
}
|
|
else if (this.#wireType === FIXED_64) {
|
|
this.#reader.skip(8);
|
|
}
|
|
else if (this.#wireType === LENGTH_DELIMITED) {
|
|
const length = this.#reader.varint();
|
|
this.#reader.skip(length);
|
|
}
|
|
else if (this.#wireType === FIXED_32) {
|
|
this.#reader.skip(4);
|
|
}
|
|
else {
|
|
throw new ProtoError(`Unexpected wire type ${this.#wireType}`);
|
|
}
|
|
this.#wireType = -1;
|
|
}
|
|
}
|
|
export function readProtobufMessage(data, def) {
|
|
const msgReader = new MessageReader(data);
|
|
const fieldReader = new FieldReader(msgReader);
|
|
let value = def.default();
|
|
while (!msgReader.eof()) {
|
|
const key = msgReader.varint();
|
|
const tag = key >> 3;
|
|
const wireType = key & 0x7;
|
|
fieldReader.setup(wireType);
|
|
const tagFun = def[tag];
|
|
if (tagFun !== undefined) {
|
|
const returnedValue = tagFun(fieldReader, value);
|
|
if (returnedValue !== undefined) {
|
|
value = returnedValue;
|
|
}
|
|
}
|
|
fieldReader.maybeSkip();
|
|
}
|
|
return value;
|
|
}
|