62 lines
1.7 KiB
JavaScript
62 lines
1.7 KiB
JavaScript
|
import Schema from './schema.js';
|
||
|
|
||
|
export default class Serializer {
|
||
|
|
||
|
constructor(schema) {
|
||
|
this.schema = schema instanceof Schema ? schema : new Schema(schema);
|
||
|
}
|
||
|
|
||
|
decode(view, destination, offset = 0) {
|
||
|
let cursor = offset;
|
||
|
for (const [key, {type}] of this.schema) {
|
||
|
const viewGetMethod = Schema.viewGetMethods[type];
|
||
|
let value;
|
||
|
if (viewGetMethod) {
|
||
|
value = view[viewGetMethod](cursor, true);
|
||
|
cursor += Schema.sizeOfType(type);
|
||
|
}
|
||
|
else {
|
||
|
switch (type) {
|
||
|
case 'string': {
|
||
|
const length = view.getUint32(cursor, true);
|
||
|
cursor += 4;
|
||
|
const {buffer, byteOffset} = view;
|
||
|
const decoder = new TextDecoder();
|
||
|
value = decoder.decode(new DataView(buffer, byteOffset + cursor, length));
|
||
|
cursor += length;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
destination[key] = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
encode(source, view, offset = 0) {
|
||
|
let cursor = offset;
|
||
|
for (const [key, {type}] of this.schema) {
|
||
|
const viewSetMethod = Schema.viewSetMethods[type];
|
||
|
if (viewSetMethod) {
|
||
|
view[viewSetMethod](cursor, source[key], true);
|
||
|
cursor += Schema.sizeOfType(type);
|
||
|
}
|
||
|
else {
|
||
|
switch (type) {
|
||
|
case 'string': {
|
||
|
const lengthOffset = cursor;
|
||
|
cursor += 4;
|
||
|
const encoder = new TextEncoder();
|
||
|
const bytes = encoder.encode(source[key]);
|
||
|
for (let i = 0; i < bytes.length; ++i) {
|
||
|
view.setUint8(cursor++, bytes[i]);
|
||
|
}
|
||
|
view.setUint32(lengthOffset, bytes.length, true);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|