Skip to content

Commit

Permalink
[JavaScript] support browser (#830)
Browse files Browse the repository at this point in the history
* feat: support browser
  • Loading branch information
theweipeng authored Aug 2, 2023
1 parent 81f7ce2 commit 0959acb
Show file tree
Hide file tree
Showing 11 changed files with 291 additions and 152 deletions.
2 changes: 1 addition & 1 deletion javascript/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"scripts": {
"test": "npm run build && enableHps=true jest",
"test": "npm run build && enableHps=true jest && ECMA_ONLY=true jest",
"build": "npm run build -w packages/fury -w packages/hps",
"lint": "eslint .",
"lint-fix": "eslint . --fix"
Expand Down
6 changes: 3 additions & 3 deletions javascript/packages/fury/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export type ToRecordType<T> = T extends {
: T extends {
type: InternalSerializerType.BINARY;
}
? Buffer
? Uint8Array
: T extends {
type: InternalSerializerType.ANY;
}
Expand All @@ -264,7 +264,7 @@ export default class {
serialize: (data: ToRecordType<T>) => {
return this.fury.serialize(data, serializer);
},
deserialize: (bytes: Buffer) => {
deserialize: (bytes: Uint8Array) => {
return this.fury.deserialize(bytes, serializer) as ToRecordType<T>;
},
};
Expand All @@ -274,7 +274,7 @@ export default class {
return this.fury.serialize(v, serialize);
}

deserialize(bytes: Buffer) {
deserialize(bytes: Uint8Array) {
return this.fury.deserialize(bytes);
}
}
3 changes: 2 additions & 1 deletion javascript/packages/fury/lib/classResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import boolSerializer from "./internalSerializer/bool";
import { uInt16Serializer, int16Serializer, int32Serializer, uInt32Serializer, uInt64Serializer, floatSerializer, doubleSerializer, uInt8Serializer, int64Serializer, int8Serializer } from "./internalSerializer/number";
import { InternalSerializerType, Serializer, Fury, BinaryReader, BinaryWriter } from "./type";
import anySerializer from './internalSerializer/any';
import { PlatformBuffer } from "./platformBuffer";

const USESTRINGVALUE = 0;
const USESTRINGID = 1
Expand Down Expand Up @@ -91,7 +92,7 @@ export default class SerializerResolver {
return this.customSerializer[tag];
}

writeTag(binaryWriter: BinaryWriter, tag: string, tagHash: number, tagBuffer: Buffer, bufferLen: number) {
writeTag(binaryWriter: BinaryWriter, tag: string, tagHash: number, tagBuffer: PlatformBuffer, bufferLen: number) {
const index = this.writeStringIndex.indexOf(tag);
if (index > -1) {
binaryWriter.uint8(USESTRINGID)
Expand Down
8 changes: 5 additions & 3 deletions javascript/packages/fury/lib/codeGen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import mapSerializer from './internalSerializer/map';
import setSerializer from './internalSerializer/set';
import { arraySerializer } from './internalSerializer/array';
import { x64hash128 } from './murmurHash3';
import { fromString } from './platformBuffer';
export interface TypeDescription {
type: InternalSerializerType,
label?: string,
Expand Down Expand Up @@ -171,7 +172,7 @@ export const genSerializer = (fury: Fury, description: TypeDescription) => {
}

fury.classResolver.registerSerializerByTag(tag, fury.classResolver.getSerializerById(InternalSerializerType.ANY));
const tagByteLen = Buffer.from(tag).byteLength;
const tagByteLen = fromString(tag).byteLength;
const expectHash = computeStructHash(description);
const read = `
// relation tag: ${Cast<ObjectTypeDescription>(description).options?.tag}
Expand All @@ -197,9 +198,9 @@ export const genSerializer = (fury: Fury, description: TypeDescription) => {
return function (fury, scope) {
const { referenceResolver, binaryWriter, classResolver, binaryReader } = fury;
const { writeNullOrRef, pushReadObject } = referenceResolver;
const { RefFlags, InternalSerializerType, arraySerializer, mapSerializer, setSerializer, x64hash128 } = scope;
const { RefFlags, InternalSerializerType, arraySerializer, mapSerializer, setSerializer, x64hash128, fromString } = scope;
${declarations.join('')}
const tagBuffer = Buffer.from("${validTag}");
const tagBuffer = fromString("${validTag}");
let tagHash = x64hash128(tagBuffer, 47).getBigUint64(0);
if (tagHash == 0) {
tagHash = 1;
Expand Down Expand Up @@ -237,5 +238,6 @@ return function (fury, scope) {
mapSerializer,
setSerializer,
x64hash128,
fromString,
}));
}
2 changes: 1 addition & 1 deletion javascript/packages/fury/lib/fury.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default (config: Config) => {
classResolver.init(fury);


function deserialize<T = any>(bytes: Buffer, serializer?: Serializer): T | null {
function deserialize<T = any>(bytes: Uint8Array, serializer?: Serializer): T | null {
referenceResolver.reset();
classResolver.reset();
binaryReader.reset(bytes);
Expand Down
125 changes: 125 additions & 0 deletions javascript/packages/fury/lib/platformBuffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright 2023 The Fury Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { isNodeEnv } from "./util";

export interface PlatformBuffer extends Uint8Array {
latin1Slice(start: number, end: number): string,
utf8Slice(start: number, end: number): string,
latin1Write(v: string, offset: number): void,
utf8Write(v: string, offset: number): void,
copy(target: Uint8Array, targetStart?: number, sourceStart?: number, sourceEnd?: number): Uint8Array
}


class BrowserBuffer extends Uint8Array {
static alloc(size: number) {
return new BrowserBuffer(new Uint8Array(size));
}

latin1Slice(start: number, end: number) {
if (end - start < 1) {
return "";
}
let str = "";
for (let i = start; i < end;) {
str += String.fromCharCode(this[i++]);
}
return str;
}

utf8Slice(start: number, end: number) {
if (end - start < 1) {
return "";
}
let str = "";
for (let i = start; i < end;) {
const t = this[i++];
if (t <= 0x7F) {
str += String.fromCharCode(t);
} else if (t >= 0xC0 && t < 0xE0) {
str += String.fromCharCode((t & 0x1F) << 6 | this[i++] & 0x3F);
} else if (t >= 0xE0 && t < 0xF0) {
str += String.fromCharCode((t & 0xF) << 12 | (this[i++] & 0x3F) << 6 | this[i++] & 0x3F);
} else if (t >= 0xF0) {
const t2 = ((t & 7) << 18 | (this[i++] & 0x3F) << 12 | (this[i++] & 0x3F) << 6 | this[i++] & 0x3F) - 0x10000;
str += String.fromCharCode(0xD800 + (t2 >> 10));
str += String.fromCharCode(0xDC00 + (t2 & 0x3FF));
}
}

return str;
}

copy(target: Uint8Array, targetStart?: number, sourceStart?: number, sourceEnd?: number) {
target.set(this.subarray(sourceStart, sourceEnd), targetStart);
}
}

export function fromString(str: string) {
if (isNodeEnv) {
return Buffer.from(str);
} else {
return new BrowserBuffer(new TextEncoder().encode(str))
}
}

export function fromUint8Array(ab: Buffer | Uint8Array): PlatformBuffer {
if (isNodeEnv) {
if (!Buffer.isBuffer(ab)) {
return (Buffer.from(ab) as unknown as PlatformBuffer)
} else {
return ab as unknown as PlatformBuffer;
}
} else {
const result = new BrowserBuffer(ab);
return result as unknown as PlatformBuffer;
}
}



export function alloc(size: number): PlatformBuffer {
if (isNodeEnv) {
return Buffer.allocUnsafe(size) as unknown as PlatformBuffer;
} else {
const result = BrowserBuffer.alloc(size);
return result as PlatformBuffer;
}
}


export function strByteLength(str: string): number {
if (isNodeEnv) {
return Buffer.byteLength(str);
} else {
let len = 0;
let c = 0;
for (let i = 0; i < str.length; ++i) {
c = str.charCodeAt(i);
if (c < 128)
len += 1;
else if (c < 2048)
len += 2;
else if ((c & 0xFC00) === 0xD800 && (str.charCodeAt(i + 1) & 0xFC00) === 0xDC00) {
++i;
len += 4;
} else
len += 3;
}
return len;
}
}
Loading

0 comments on commit 0959acb

Please sign in to comment.