Skip to content

Commit

Permalink
feat(JavaScript): Make PlatformBuffer available if has Buffer polyfill
Browse files Browse the repository at this point in the history
  • Loading branch information
bytemain committed Feb 18, 2024
1 parent ba37400 commit 8b30045
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 29 deletions.
2 changes: 1 addition & 1 deletion javascript/packages/fury/lib/gen/any.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class AnySerializer {
const typeId = this.fury.binaryReader.int16();
let serializer: Serializer;
if (typeId === InternalSerializerType.FURY_TYPE_TAG) {
const tag = this.fury.classResolver.readTag(this.fury.binaryReader)();
const tag = this.fury.classResolver.readTag(this.fury.binaryReader)()!;
serializer = this.fury.classResolver.getSerializerByTag(tag);
} else {
serializer = this.fury.classResolver.getSerializerById(typeId);
Expand Down
6 changes: 3 additions & 3 deletions javascript/packages/fury/lib/gen/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import { Scope } from "./scope";
import { TypeDescription, ObjectTypeDescription } from "../description";

export interface SerializerGenerator {
toSerializer(): string;
toWriteEmbed(accessor: string, excludeHead?: boolean): string;
toReadEmbed(accessor: (expr: string) => string, excludeHead?: boolean, refState?: RefState): string;
toSerializer(): string
toWriteEmbed(accessor: string, excludeHead?: boolean): string
toReadEmbed(accessor: (expr: string) => string, excludeHead?: boolean, refState?: RefState): string
}

export enum RefStateType {
Expand Down
39 changes: 28 additions & 11 deletions javascript/packages/fury/lib/platformBuffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,40 @@
* under the License.
*/

import { isNodeEnv } from "./util";
import { hasBuffer } from "./util";

export type SupportedEncodings = "latin1" | "utf8";

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): void;
toString(encoding?: SupportedEncodings, start?: number, end?: number,): string
write(string: string, offset: number, encoding?: SupportedEncodings): void
copy(target: Uint8Array, targetStart?: number, sourceStart?: number, sourceEnd?: number): void
}

export class BrowserBuffer extends Uint8Array implements PlatformBuffer {
write(string: string, offset: number, encoding: SupportedEncodings = "utf8"): void {
if (encoding === "latin1") {
return this.latin1Write(string, offset);
}
return this.utf8Write(string, offset);
}

toString(encoding: SupportedEncodings = "utf8", start = 0, end?: number): string {
end = end || this.length;

if (encoding === "latin1") {
return this.latin1Slice(start, end);
}
return this.utf8Slice(start, end);
}

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

latin1Write(string: string, offset: number) {
for (let index = 0; index < string.length; index++) {
let index = 0;
for (; index < string.length; index++) {
this[offset++] = string.charCodeAt(index);
}
}
Expand Down Expand Up @@ -122,7 +139,7 @@ export class BrowserBuffer extends Uint8Array implements PlatformBuffer {
}
}

export const fromUint8Array = isNodeEnv
export const fromUint8Array = hasBuffer
? (ab: Buffer | Uint8Array) => {
if (!Buffer.isBuffer(ab)) {
return (Buffer.from(ab) as unknown as PlatformBuffer);
Expand All @@ -132,14 +149,14 @@ export const fromUint8Array = isNodeEnv
}
: (ab: Buffer | Uint8Array) => new BrowserBuffer(ab);

export const alloc = (isNodeEnv ? Buffer.allocUnsafe : BrowserBuffer.alloc) as unknown as (size: number) => PlatformBuffer;
export const alloc = (hasBuffer ? Buffer.allocUnsafe : BrowserBuffer.alloc) as unknown as (size: number) => PlatformBuffer;

export const strByteLength = isNodeEnv ? Buffer.byteLength : BrowserBuffer.byteLength;
export const strByteLength = hasBuffer ? Buffer.byteLength : BrowserBuffer.byteLength;

let utf8Encoder: TextEncoder | null;

export const fromString
= isNodeEnv
= hasBuffer
? (str: string) => Buffer.from(str) as unknown as PlatformBuffer
: (str: string) => {
if (!utf8Encoder) {
Expand Down
6 changes: 3 additions & 3 deletions javascript/packages/fury/lib/reader/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const BinaryReader = (config: Config) => {
byteLength = buffer.byteLength;
dataView = new DataView(buffer.buffer, buffer.byteOffset);
if (sliceStringEnable) {
bigString = buffer.latin1Slice(0, byteLength);
bigString = buffer.toString("latin1", 0, byteLength);
}
cursor = 0;
}
Expand Down Expand Up @@ -113,11 +113,11 @@ export const BinaryReader = (config: Config) => {
}

function stringUtf8At(start: number, len: number) {
return buffer.utf8Slice(start, start + len);
return buffer.toString("utf8", start, start + len);
}

function stringUtf8(len: number) {
const result = buffer.utf8Slice(cursor, cursor + len);
const result = buffer.toString("utf8", cursor, cursor + len);
cursor += len;
return result;
}
Expand Down
2 changes: 1 addition & 1 deletion javascript/packages/fury/lib/reader/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,6 @@ export const readLatin1String = (buffer: PlatformBuffer, len: number, cursor: nu
case 15:
return read15(buffer, cursor);
default:
return buffer.latin1Slice(cursor, cursor + len);
return buffer.toString("latin1", cursor, cursor + len,);
}
};
2 changes: 2 additions & 0 deletions javascript/packages/fury/lib/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ export const isNodeEnv: boolean
&& process.versions != null
&& process.env.ECMA_ONLY !== "true"
&& process.versions.node != null;

export const hasBuffer = isNodeEnv && typeof Buffer !== "undefined";
6 changes: 3 additions & 3 deletions javascript/packages/fury/lib/writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export const BinaryWriter = (config: Config) => {
if (len < 40) {
fastWriteStringUtf8(v, arrayBuffer, cursor);
} else {
arrayBuffer.utf8Write(v, cursor);
arrayBuffer.write(v, cursor, "utf8");
}
}
cursor += len;
Expand All @@ -213,13 +213,13 @@ export const BinaryWriter = (config: Config) => {
arrayBuffer[cursor + index] = v.charCodeAt(index);
}
} else {
arrayBuffer.latin1Write(v, cursor);
arrayBuffer.write(v, cursor, "latin1");
}
} else {
if (len < 40) {
fastWriteStringUtf8(v, arrayBuffer, cursor);
} else {
arrayBuffer.utf8Write(v, cursor);
arrayBuffer.write(v, cursor, "utf8");
}
}
cursor += len;
Expand Down
51 changes: 45 additions & 6 deletions javascript/test/platformBuffer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import { fromUint8Array, alloc, BrowserBuffer } from '../packages/fury/lib/platformBuffer';
import { fromUint8Array, alloc, BrowserBuffer, PlatformBuffer } from '../packages/fury/lib/platformBuffer';
import { describe, expect, test } from '@jest/globals';

describe('platformBuffer', () => {
Expand All @@ -38,22 +38,54 @@ describe('platformBuffer', () => {
});


test('should latin1 work', () => {
test('should latin1Write work', () => {
const bb = BrowserBuffer.alloc(100);
bb.latin1Write("hello, world", 0);

const str = bb.latin1Slice(0, 12);
expect(str).toBe("hello, world");

const str2 = bb.toString('latin1', 0, 12);
expect(str2).toBe("hello, world");
});

test('should write latin1 work', () => {
const bb = BrowserBuffer.alloc(100);
bb.write("hello, world", 0, 'latin1');

const str = bb.latin1Slice(0, 12);
expect(str).toBe("hello, world");

const str2 = bb.toString('latin1', 0, 12);
expect(str2).toBe("hello, world");
});


test('should utf8Write work', () => {
const rawStr = "我是Fury, 你好!😁א";
const bb = BrowserBuffer.alloc(100);
bb.utf8Write(rawStr, 0);

const str = bb.utf8Slice(0, 27);
expect(str).toBe(rawStr);

const str2 = bb.toString('utf8', 0, 27);
expect(str2).toBe(rawStr);
});

test('should utf8 work', () => {
const rawStr = "我是Fury, 你好!😁א";
const bb = BrowserBuffer.alloc(100);
bb.utf8Write("我是Fury, 你好!😁א", 0);
bb.write(rawStr, 0, 'utf8');

const str = bb.utf8Slice(0, 27);
expect(str).toBe("我是Fury, 你好!😁א");
expect(str).toBe(rawStr);

const str2 = bb.toString('utf8', 0, 27);
expect(str2).toBe(rawStr);
});


test('should byteLength work', () => {
expect(BrowserBuffer.byteLength("hello, world")).toBe(12);
expect(BrowserBuffer.byteLength("我是Fury, 你好!😁א")).toBe(27);
Expand All @@ -66,6 +98,13 @@ describe('platformBuffer', () => {
bb.copy(target, 0, 0, 5);
expect([...target]).toEqual([ 104, 101, 108, 108, 111 ])
});
});


test('Buffer can be assigned to PlatformBuffer', () => {
const cc = Buffer.alloc(20);
cc.write("hello", 0, "latin1");
const bb: PlatformBuffer = cc;
expect(bb.toString('latin1', 0 , 5)).toBe("hello");
bb.write("world", 5, "latin1");
expect(bb.toString('latin1', 0, 10)).toBe("helloworld");
})
});
2 changes: 1 addition & 1 deletion javascript/test/reader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('reader', () => {

test('should bufferRef work', () => {
const bb = alloc(100);
bb.latin1Write("hello", 0);
bb.write("hello", 0, 'latin1');
const target = new Uint8Array(5);
bb.copy(target, 0, 0, 5);
expect([...target]).toEqual([ 104, 101, 108, 108, 111 ])
Expand Down

0 comments on commit 8b30045

Please sign in to comment.