format
This commit is contained in:
@ -3,3 +3,4 @@ package-lock.json
|
|||||||
dist
|
dist
|
||||||
build
|
build
|
||||||
coverage
|
coverage
|
||||||
|
test
|
||||||
|
|||||||
@ -2,4 +2,3 @@
|
|||||||
"semi": false,
|
"semi": false,
|
||||||
"singleQuote": true
|
"singleQuote": true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { dts } from "rollup-plugin-dts";
|
import { dts } from 'rollup-plugin-dts'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
input: 'types/index.d.ts',
|
input: 'types/index.d.ts',
|
||||||
output: {
|
output: {
|
||||||
file: 'dist/index.d.ts',
|
file: 'dist/index.d.ts',
|
||||||
format: 'es',
|
format: 'es',
|
||||||
},
|
},
|
||||||
plugins: [dts()],
|
plugins: [dts()],
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,12 @@
|
|||||||
import { isHeadless, isSerializableType, parse, serialize, sizeof, sizeofHead, Type } from "."
|
import {
|
||||||
|
isHeadless,
|
||||||
|
isSerializableType,
|
||||||
|
parse,
|
||||||
|
serialize,
|
||||||
|
sizeof,
|
||||||
|
sizeofHead,
|
||||||
|
Type,
|
||||||
|
} from '.'
|
||||||
|
|
||||||
export function ConstArray(size) {
|
export function ConstArray(size) {
|
||||||
const obj = { _size: size }
|
const obj = { _size: size }
|
||||||
@ -6,22 +14,34 @@ export function ConstArray(size) {
|
|||||||
obj.new(ConstArray, arguments)
|
obj.new(ConstArray, arguments)
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
ConstArray.prototype.serialize = function(dv, src, ...inner_types) {
|
ConstArray.prototype.serialize = function (dv, src, ...inner_types) {
|
||||||
const item_headless = isHeadless(...inner_types)
|
const item_headless = isHeadless(...inner_types)
|
||||||
const item_head_size = sizeofHead(src[0], ...inner_types)
|
const item_head_size = sizeofHead(src[0], ...inner_types)
|
||||||
const size = this._size
|
const size = this._size
|
||||||
|
|
||||||
if (dv.byteLength < this.sizeof(src, ...inner_types)) {
|
if (dv.byteLength < this.sizeof(src, ...inner_types)) {
|
||||||
throw new Error(this.name_+ ', ' + inner_types.join(', ') + ' too small buffer')
|
throw new Error(
|
||||||
|
this.name_ + ', ' + inner_types.join(', ') + ' too small buffer',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (src.length != size) {
|
if (src.length != size) {
|
||||||
throw new Error(this.name_+ ', ' + inner_types.join(', ') + ' should be ' + size + ' elements length')
|
throw new Error(
|
||||||
|
this.name_ +
|
||||||
|
', ' +
|
||||||
|
inner_types.join(', ') +
|
||||||
|
' should be ' +
|
||||||
|
size +
|
||||||
|
' elements length',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let offset = item_head_size * size
|
let offset = item_head_size * size
|
||||||
|
|
||||||
for (let i = 0; i < size; i++) {
|
for (let i = 0; i < size; i++) {
|
||||||
const item_head_frame = new DataView(dv.buffer, dv.byteOffset + item_head_size * i)
|
const item_head_frame = new DataView(
|
||||||
|
dv.buffer,
|
||||||
|
dv.byteOffset + item_head_size * i,
|
||||||
|
)
|
||||||
if (item_headless) {
|
if (item_headless) {
|
||||||
item_head_frame.setUint32(0, offset)
|
item_head_frame.setUint32(0, offset)
|
||||||
const item_frame = new DataView(dv.buffer, dv.byteOffset + offset)
|
const item_frame = new DataView(dv.buffer, dv.byteOffset + offset)
|
||||||
@ -33,14 +53,17 @@ ConstArray.prototype.serialize = function(dv, src, ...inner_types) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ConstArray.prototype.parse = function(dv, ...inner_types) {
|
ConstArray.prototype.parse = function (dv, ...inner_types) {
|
||||||
const item_headless = isHeadless(...inner_types)
|
const item_headless = isHeadless(...inner_types)
|
||||||
const item_head_size = sizeofHead(...inner_types)
|
const item_head_size = sizeofHead(...inner_types)
|
||||||
const size = this._size
|
const size = this._size
|
||||||
const array = Array(size)
|
const array = Array(size)
|
||||||
|
|
||||||
for (let i = 0; i < size; i++) {
|
for (let i = 0; i < size; i++) {
|
||||||
const item_head_frame = new DataView(dv.buffer, dv.byteOffset + item_head_size * i)
|
const item_head_frame = new DataView(
|
||||||
|
dv.buffer,
|
||||||
|
dv.byteOffset + item_head_size * i,
|
||||||
|
)
|
||||||
if (item_headless) {
|
if (item_headless) {
|
||||||
const offset = item_head_frame.getUint32(0)
|
const offset = item_head_frame.getUint32(0)
|
||||||
const item_frame = new DataView(dv.buffer, dv.byteOffset + offset)
|
const item_frame = new DataView(dv.buffer, dv.byteOffset + offset)
|
||||||
@ -52,10 +75,10 @@ ConstArray.prototype.parse = function(dv, ...inner_types) {
|
|||||||
|
|
||||||
return array
|
return array
|
||||||
}
|
}
|
||||||
ConstArray.prototype.isHeadless = function(...inner_types) {
|
ConstArray.prototype.isHeadless = function (...inner_types) {
|
||||||
return isHeadless(...inner_types)
|
return isHeadless(...inner_types)
|
||||||
}
|
}
|
||||||
ConstArray.prototype.sizeof = function(arg, ...args) {
|
ConstArray.prototype.sizeof = function (arg, ...args) {
|
||||||
let inner_types
|
let inner_types
|
||||||
let src
|
let src
|
||||||
|
|
||||||
@ -68,10 +91,12 @@ ConstArray.prototype.sizeof = function(arg, ...args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fixed_size = sizeofHead(...inner_types) * this._size
|
const fixed_size = sizeofHead(...inner_types) * this._size
|
||||||
|
|
||||||
if (isHeadless(...inner_types)) {
|
if (isHeadless(...inner_types)) {
|
||||||
if (src == undefined) {
|
if (src == undefined) {
|
||||||
throw new Error('unknown sizeof ' + this._name + ', ' + inner_types.join(','))
|
throw new Error(
|
||||||
|
'unknown sizeof ' + this._name + ', ' + inner_types.join(','),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let variable_size = 0
|
let variable_size = 0
|
||||||
@ -82,7 +107,7 @@ ConstArray.prototype.sizeof = function(arg, ...args) {
|
|||||||
return fixed_size + variable_size
|
return fixed_size + variable_size
|
||||||
} else {
|
} else {
|
||||||
return fixed_size
|
return fixed_size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Object.setPrototypeOf(ConstArray.prototype, Type.prototype)
|
Object.setPrototypeOf(ConstArray.prototype, Type.prototype)
|
||||||
Object.freeze(ConstArray.prototype)
|
Object.freeze(ConstArray.prototype)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { memcpy, Type } from "."
|
import { memcpy, Type } from '.'
|
||||||
|
|
||||||
export function ConstDataView(size) {
|
export function ConstDataView(size) {
|
||||||
const obj = { _size: size }
|
const obj = { _size: size }
|
||||||
@ -6,7 +6,7 @@ export function ConstDataView(size) {
|
|||||||
obj.new(ConstDataView, arguments)
|
obj.new(ConstDataView, arguments)
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
ConstDataView.prototype.serialize = function(dv, src) {
|
ConstDataView.prototype.serialize = function (dv, src) {
|
||||||
if (dv.byteLength < this._size) {
|
if (dv.byteLength < this._size) {
|
||||||
throw new Error(this._name + ' too small buffer')
|
throw new Error(this._name + ' too small buffer')
|
||||||
}
|
}
|
||||||
@ -16,7 +16,7 @@ ConstDataView.prototype.serialize = function(dv, src) {
|
|||||||
memcpy(dv, src)
|
memcpy(dv, src)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ConstDataView.prototype.parse = function(dv) {
|
ConstDataView.prototype.parse = function (dv) {
|
||||||
const res_buffer = new ArrayBuffer(this._size)
|
const res_buffer = new ArrayBuffer(this._size)
|
||||||
const res_dv = new DataView(res_buffer)
|
const res_dv = new DataView(res_buffer)
|
||||||
|
|
||||||
@ -24,10 +24,10 @@ ConstDataView.prototype.parse = function(dv) {
|
|||||||
|
|
||||||
return res_dv
|
return res_dv
|
||||||
}
|
}
|
||||||
ConstDataView.prototype.isHeadless = function() {
|
ConstDataView.prototype.isHeadless = function () {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
ConstDataView.prototype.sizeof = function() {
|
ConstDataView.prototype.sizeof = function () {
|
||||||
return this._size
|
return this._size
|
||||||
}
|
}
|
||||||
Object.setPrototypeOf(ConstDataView.prototype, Type.prototype)
|
Object.setPrototypeOf(ConstDataView.prototype, Type.prototype)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { memcpy } from "./mem"
|
import { memcpy } from './mem'
|
||||||
import { Type } from "./Type"
|
import { Type } from './Type'
|
||||||
|
|
||||||
export function ConstString(size) {
|
export function ConstString(size) {
|
||||||
const obj = { _size: size }
|
const obj = { _size: size }
|
||||||
@ -7,7 +7,7 @@ export function ConstString(size) {
|
|||||||
obj.new(ConstString, arguments)
|
obj.new(ConstString, arguments)
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
ConstString.prototype.serialize = function(dv, src) {
|
ConstString.prototype.serialize = function (dv, src) {
|
||||||
const encoder = new TextEncoder('utf-8')
|
const encoder = new TextEncoder('utf-8')
|
||||||
const encoded = new DataView(encoder.encode(src).buffer, 0, this._size)
|
const encoded = new DataView(encoder.encode(src).buffer, 0, this._size)
|
||||||
|
|
||||||
@ -21,15 +21,15 @@ ConstString.prototype.serialize = function(dv, src) {
|
|||||||
memcpy(dv, encoded)
|
memcpy(dv, encoded)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ConstString.prototype.parse = function(dv) {
|
ConstString.prototype.parse = function (dv) {
|
||||||
const frame = new DataView(dv.buffer, dv.byteOffset, this._size)
|
const frame = new DataView(dv.buffer, dv.byteOffset, this._size)
|
||||||
const decoder = new TextDecoder('utf-8')
|
const decoder = new TextDecoder('utf-8')
|
||||||
return decoder.decode(frame)
|
return decoder.decode(frame)
|
||||||
}
|
}
|
||||||
ConstString.prototype.isHeadless = function() {
|
ConstString.prototype.isHeadless = function () {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
ConstString.prototype.sizeof = function() {
|
ConstString.prototype.sizeof = function () {
|
||||||
return this._size
|
return this._size
|
||||||
}
|
}
|
||||||
Object.setPrototypeOf(ConstString.prototype, Type.prototype)
|
Object.setPrototypeOf(ConstString.prototype, Type.prototype)
|
||||||
|
|||||||
100
src/Int.js
100
src/Int.js
@ -6,58 +6,58 @@ export function Int(bits, sign) {
|
|||||||
obj.new(Int, arguments)
|
obj.new(Int, arguments)
|
||||||
|
|
||||||
switch (sign) {
|
switch (sign) {
|
||||||
case 'signed':
|
case 'signed':
|
||||||
switch (bits) {
|
switch (bits) {
|
||||||
case 8:
|
case 8:
|
||||||
obj._dv_set = DataView.prototype.setInt8
|
obj._dv_set = DataView.prototype.setInt8
|
||||||
obj._dv_get = DataView.prototype.getInt8
|
obj._dv_get = DataView.prototype.getInt8
|
||||||
obj._limits = limits.i8
|
obj._limits = limits.i8
|
||||||
|
break
|
||||||
|
|
||||||
|
case 16:
|
||||||
|
obj._dv_set = DataView.prototype.setInt16
|
||||||
|
obj._dv_get = DataView.prototype.getInt16
|
||||||
|
obj._limits = limits.i16
|
||||||
|
break
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
obj._dv_set = DataView.prototype.setInt32
|
||||||
|
obj._dv_get = DataView.prototype.getInt32
|
||||||
|
obj._limits = limits.i32
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error(obj._name + ' incorrect bits ' + bits)
|
||||||
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
case 16:
|
case 'unsigned':
|
||||||
obj._dv_set = DataView.prototype.setInt16
|
switch (bits) {
|
||||||
obj._dv_get = DataView.prototype.getInt16
|
case 8:
|
||||||
obj._limits = limits.i16
|
obj._dv_set = DataView.prototype.setUint8
|
||||||
break
|
obj._dv_get = DataView.prototype.getUint8
|
||||||
|
obj._limits = limits.u8
|
||||||
|
break
|
||||||
|
|
||||||
case 32:
|
case 16:
|
||||||
obj._dv_set = DataView.prototype.setInt32
|
obj._dv_set = DataView.prototype.setUint16
|
||||||
obj._dv_get = DataView.prototype.getInt32
|
obj._dv_get = DataView.prototype.getUint16
|
||||||
obj._limits = limits.i32
|
obj._limits = limits.u16
|
||||||
|
break
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
obj._dv_set = DataView.prototype.setUint32
|
||||||
|
obj._dv_get = DataView.prototype.getUint32
|
||||||
|
obj._limits = limits.u32
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error(obj._name + ' incorrect bits ' + bits)
|
||||||
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error(obj._name + ' incorrect bits ' + bits)
|
throw new Error(obj._name + ' incorrect sign ' + sign)
|
||||||
}
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'unsigned':
|
|
||||||
switch (bits) {
|
|
||||||
case 8:
|
|
||||||
obj._dv_set = DataView.prototype.setUint8
|
|
||||||
obj._dv_get = DataView.prototype.getUint8
|
|
||||||
obj._limits = limits.u8
|
|
||||||
break
|
|
||||||
|
|
||||||
case 16:
|
|
||||||
obj._dv_set = DataView.prototype.setUint16
|
|
||||||
obj._dv_get = DataView.prototype.getUint16
|
|
||||||
obj._limits = limits.u16
|
|
||||||
break
|
|
||||||
|
|
||||||
case 32:
|
|
||||||
obj._dv_set = DataView.prototype.setUint32
|
|
||||||
obj._dv_get = DataView.prototype.getUint32
|
|
||||||
obj._limits = limits.u32
|
|
||||||
break
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new Error(obj._name + ' incorrect bits ' + bits)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new Error(obj._name + ' incorrect sign ' + sign)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
@ -67,10 +67,14 @@ Int.prototype.serialize = function (dv, src) {
|
|||||||
throw new Error(this._name + ' buffer is too small')
|
throw new Error(this._name + ' buffer is too small')
|
||||||
}
|
}
|
||||||
if (src > this._limits.MAX_VALUE) {
|
if (src > this._limits.MAX_VALUE) {
|
||||||
throw new Error(this._name + ` should be less or equal than ` + this._limits.MAX_VALUE)
|
throw new Error(
|
||||||
|
this._name + ` should be less or equal than ` + this._limits.MAX_VALUE,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (src < this._limits.MIN_VALUE) {
|
if (src < this._limits.MIN_VALUE) {
|
||||||
throw new Error(this._name + ` should be more or equal than ` + this._limits.MIN_VALUE)
|
throw new Error(
|
||||||
|
this._name + ` should be more or equal than ` + this._limits.MIN_VALUE,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
this._dv_set.call(dv, 0, src)
|
this._dv_set.call(dv, 0, src)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { isHeadless, parse, serialize, sizeof, sizeofHead, Type } from "."
|
import { isHeadless, parse, serialize, sizeof, sizeofHead, Type } from '.'
|
||||||
|
|
||||||
export function Struct(type_obj) {
|
export function Struct(type_obj) {
|
||||||
const obj = {}
|
const obj = {}
|
||||||
Object.setPrototypeOf(obj, Struct.prototype)
|
Object.setPrototypeOf(obj, Struct.prototype)
|
||||||
|
|
||||||
obj._info_by_key = new Map
|
obj._info_by_key = new Map()
|
||||||
obj._headless = false
|
obj._headless = false
|
||||||
|
|
||||||
const arg = {}
|
const arg = {}
|
||||||
let offset = 0
|
let offset = 0
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ export function Struct(type_obj) {
|
|||||||
types = [value]
|
types = [value]
|
||||||
}
|
}
|
||||||
|
|
||||||
arg[key] = types.map(type => type.name)
|
arg[key] = types.map((type) => type.name)
|
||||||
|
|
||||||
const headless = isHeadless(...types)
|
const headless = isHeadless(...types)
|
||||||
obj._info_by_key.set(key, {
|
obj._info_by_key.set(key, {
|
||||||
@ -35,12 +35,12 @@ export function Struct(type_obj) {
|
|||||||
|
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
Struct.prototype.serialize = function(dv, src) {
|
Struct.prototype.serialize = function (dv, src) {
|
||||||
let data_offset = this._size
|
let data_offset = this._size
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(src)) {
|
for (const [key, value] of Object.entries(src)) {
|
||||||
const info = this._info_by_key.get(key)
|
const info = this._info_by_key.get(key)
|
||||||
|
|
||||||
if (info.headless) {
|
if (info.headless) {
|
||||||
dv.setUint32(info.offset, data_offset)
|
dv.setUint32(info.offset, data_offset)
|
||||||
const frame = new DataView(dv.buffer, dv.byteOffset + data_offset)
|
const frame = new DataView(dv.buffer, dv.byteOffset + data_offset)
|
||||||
@ -52,10 +52,10 @@ Struct.prototype.serialize = function(dv, src) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Struct.prototype.parse = function(dv) {
|
Struct.prototype.parse = function (dv) {
|
||||||
const res = {}
|
const res = {}
|
||||||
|
|
||||||
for (const [key, info] of this._info_by_key.entries()) {
|
for (const [key, info] of this._info_by_key.entries()) {
|
||||||
if (info.headless) {
|
if (info.headless) {
|
||||||
const data_offset = dv.getUint32(info.offset)
|
const data_offset = dv.getUint32(info.offset)
|
||||||
const frame = new DataView(dv.buffer, dv.byteOffset + data_offset)
|
const frame = new DataView(dv.buffer, dv.byteOffset + data_offset)
|
||||||
@ -68,10 +68,10 @@ Struct.prototype.parse = function(dv) {
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
Struct.prototype.isHeadless = function() {
|
Struct.prototype.isHeadless = function () {
|
||||||
return this._headless
|
return this._headless
|
||||||
}
|
}
|
||||||
Struct.prototype.sizeof = function(arg) {
|
Struct.prototype.sizeof = function (arg) {
|
||||||
if (this._headless) {
|
if (this._headless) {
|
||||||
if (arg === undefined) {
|
if (arg === undefined) {
|
||||||
throw new Error('unknown size of ' + this)
|
throw new Error('unknown size of ' + this)
|
||||||
|
|||||||
@ -3,17 +3,17 @@ export function Type() {
|
|||||||
Object.setPrototypeOf(obj, Type.prototype)
|
Object.setPrototypeOf(obj, Type.prototype)
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
Type.prototype.new = function(func, args) {
|
Type.prototype.new = function (func, args) {
|
||||||
this._name = func.name
|
this._name = func.name
|
||||||
if (args !== undefined) {
|
if (args !== undefined) {
|
||||||
const str_args = Array.from(args).map(arg => JSON.stringify(arg))
|
const str_args = Array.from(args).map((arg) => JSON.stringify(arg))
|
||||||
this._name += '(' + str_args.join(', ') + ')'
|
this._name += '(' + str_args.join(', ') + ')'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Type.prototype.toString = function() {
|
Type.prototype.toString = function () {
|
||||||
return this._name
|
return this._name
|
||||||
}
|
}
|
||||||
Type.prototype.serialize = function() {
|
Type.prototype.serialize = function () {
|
||||||
throw new Error('should be overloaded')
|
throw new Error('should be overloaded')
|
||||||
}
|
}
|
||||||
Type.prototype.parse = Type.prototype.serialize
|
Type.prototype.parse = Type.prototype.serialize
|
||||||
|
|||||||
45
src/index.js
45
src/index.js
@ -1,13 +1,22 @@
|
|||||||
import { limits } from "./limits"
|
import { limits } from './limits'
|
||||||
import { memcpy } from "./mem"
|
import { memcpy } from './mem'
|
||||||
import { Type } from "./Type"
|
import { Type } from './Type'
|
||||||
import { Int } from "./Int"
|
import { Int } from './Int'
|
||||||
import { ConstString } from './ConstString'
|
import { ConstString } from './ConstString'
|
||||||
import { ConstArray } from "./ConstArray"
|
import { ConstArray } from './ConstArray'
|
||||||
import { ConstDataView } from './ConstDataView'
|
import { ConstDataView } from './ConstDataView'
|
||||||
import { Struct } from './Struct'
|
import { Struct } from './Struct'
|
||||||
|
|
||||||
export { limits, memcpy, Type, Int, ConstString, ConstArray, ConstDataView, Struct }
|
export {
|
||||||
|
limits,
|
||||||
|
memcpy,
|
||||||
|
Type,
|
||||||
|
Int,
|
||||||
|
ConstString,
|
||||||
|
ConstArray,
|
||||||
|
ConstDataView,
|
||||||
|
Struct,
|
||||||
|
}
|
||||||
|
|
||||||
export function serialize(dv, src, ...types) {
|
export function serialize(dv, src, ...types) {
|
||||||
const [type, ...inner_types] = types
|
const [type, ...inner_types] = types
|
||||||
@ -60,7 +69,10 @@ export function serialize(dv, src, ...types) {
|
|||||||
let offset = 4 + item_head_size * size
|
let offset = 4 + item_head_size * size
|
||||||
|
|
||||||
for (let i = 0; i < size; i++) {
|
for (let i = 0; i < size; i++) {
|
||||||
const item_head_frame = new DataView(dv.buffer, dv.byteOffset + 4 + item_head_size * i)
|
const item_head_frame = new DataView(
|
||||||
|
dv.buffer,
|
||||||
|
dv.byteOffset + 4 + item_head_size * i,
|
||||||
|
)
|
||||||
if (item_headless) {
|
if (item_headless) {
|
||||||
item_head_frame.setUint32(0, offset)
|
item_head_frame.setUint32(0, offset)
|
||||||
const item_frame = new DataView(dv.buffer, dv.byteOffset + offset)
|
const item_frame = new DataView(dv.buffer, dv.byteOffset + offset)
|
||||||
@ -114,7 +126,10 @@ export function parse(dv, ...types) {
|
|||||||
const array = Array(size)
|
const array = Array(size)
|
||||||
|
|
||||||
for (let i = 0; i < size; i++) {
|
for (let i = 0; i < size; i++) {
|
||||||
const item_head_frame = new DataView(dv.buffer, dv.byteOffset + 4 + item_head_size * i)
|
const item_head_frame = new DataView(
|
||||||
|
dv.buffer,
|
||||||
|
dv.byteOffset + 4 + item_head_size * i,
|
||||||
|
)
|
||||||
if (item_headless) {
|
if (item_headless) {
|
||||||
const offset = item_head_frame.getUint32(0)
|
const offset = item_head_frame.getUint32(0)
|
||||||
const item_frame = new DataView(dv.buffer, dv.byteOffset + offset)
|
const item_frame = new DataView(dv.buffer, dv.byteOffset + offset)
|
||||||
@ -146,12 +161,14 @@ export function isHeadless(...args) {
|
|||||||
if (arg instanceof Type) {
|
if (arg instanceof Type) {
|
||||||
return arg.isHeadless(...inner_args)
|
return arg.isHeadless(...inner_args)
|
||||||
}
|
}
|
||||||
return arg == Array ||
|
return (
|
||||||
|
arg == Array ||
|
||||||
arg == String ||
|
arg == String ||
|
||||||
arg == DataView ||
|
arg == DataView ||
|
||||||
Array.isArray(arg) ||
|
Array.isArray(arg) ||
|
||||||
typeof arg == 'string' ||
|
typeof arg == 'string' ||
|
||||||
arg instanceof DataView
|
arg instanceof DataView
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sizeofHead(...args) {
|
export function sizeofHead(...args) {
|
||||||
@ -166,10 +183,10 @@ export function sizeof(...args) {
|
|||||||
const [arg, ...inner_args] = args
|
const [arg, ...inner_args] = args
|
||||||
const [arg2, ...inner_args2] = inner_args
|
const [arg2, ...inner_args2] = inner_args
|
||||||
|
|
||||||
if (arg == Boolean || arg2 == Boolean && typeof arg == 'boolean') {
|
if (arg == Boolean || (arg2 == Boolean && typeof arg == 'boolean')) {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
if (arg == Number || arg2 == Number && typeof arg == 'number') {
|
if (arg == Number || (arg2 == Number && typeof arg == 'number')) {
|
||||||
return 8
|
return 8
|
||||||
}
|
}
|
||||||
if (arg2 == String && typeof arg == 'string') {
|
if (arg2 == String && typeof arg == 'string') {
|
||||||
@ -177,10 +194,8 @@ export function sizeof(...args) {
|
|||||||
return 4 + encoder.encode(arg).byteLength
|
return 4 + encoder.encode(arg).byteLength
|
||||||
}
|
}
|
||||||
if (arg2 == Array && Array.isArray(arg)) {
|
if (arg2 == Array && Array.isArray(arg)) {
|
||||||
|
|
||||||
const fixed_size = 4 + sizeofHead(...inner_args2) * arg.length
|
const fixed_size = 4 + sizeofHead(...inner_args2) * arg.length
|
||||||
if (isHeadless(...inner_args2)) {
|
if (isHeadless(...inner_args2)) {
|
||||||
|
|
||||||
let variable_size = 0
|
let variable_size = 0
|
||||||
for (const item of arg) {
|
for (const item of arg) {
|
||||||
variable_size += sizeof(item, ...inner_args2)
|
variable_size += sizeof(item, ...inner_args2)
|
||||||
@ -204,10 +219,12 @@ export function sizeof(...args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isSerializableType(type) {
|
export function isSerializableType(type) {
|
||||||
return type == Boolean ||
|
return (
|
||||||
|
type == Boolean ||
|
||||||
type == Number ||
|
type == Number ||
|
||||||
type == String ||
|
type == String ||
|
||||||
type == Array ||
|
type == Array ||
|
||||||
type == DataView ||
|
type == DataView ||
|
||||||
type instanceof Type
|
type instanceof Type
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,16 +35,16 @@ const bool = {
|
|||||||
MAX_VALUE: 1,
|
MAX_VALUE: 1,
|
||||||
}
|
}
|
||||||
const f32 = {
|
const f32 = {
|
||||||
MIN_VALUE: -3.40282347e+38,
|
MIN_VALUE: -3.40282347e38,
|
||||||
MAX_VALUE: 3.40282347e+38,
|
MAX_VALUE: 3.40282347e38,
|
||||||
MIN_NORMAL_VALUE: 1.17549435e-38,
|
MIN_NORMAL_VALUE: 1.17549435e-38,
|
||||||
MIN_SAFE_INTEGER: -16777215,
|
MIN_SAFE_INTEGER: -16777215,
|
||||||
MAX_SAFE_INTEGER: 16777215,
|
MAX_SAFE_INTEGER: 16777215,
|
||||||
EPSILON: 1.19209290e-07,
|
EPSILON: 1.1920929e-7,
|
||||||
}
|
}
|
||||||
const f64 = {
|
const f64 = {
|
||||||
MIN_VALUE: -1.7976931348623157e+308,
|
MIN_VALUE: -1.7976931348623157e308,
|
||||||
MAX_VALUE: 1.7976931348623157e+308,
|
MAX_VALUE: 1.7976931348623157e308,
|
||||||
MIN_NORMAL_VALUE: 2.2250738585072014e-308,
|
MIN_NORMAL_VALUE: 2.2250738585072014e-308,
|
||||||
MIN_SAFE_INTEGER: -9007199254740991,
|
MIN_SAFE_INTEGER: -9007199254740991,
|
||||||
MAX_SAFE_INTEGER: 9007199254740991,
|
MAX_SAFE_INTEGER: 9007199254740991,
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
export function memcpy(dest, src) {
|
export function memcpy(dest, src) {
|
||||||
const min_size = dest.byteLength > src.byteLength ?
|
const min_size =
|
||||||
src.byteLength : dest.byteLength
|
dest.byteLength > src.byteLength ? src.byteLength : dest.byteLength
|
||||||
|
|
||||||
for (let i = 0; i < Math.floor(min_size / 8); i++) {
|
for (let i = 0; i < Math.floor(min_size / 8); i++) {
|
||||||
dest.setFloat64(i * 8, src.getFloat64(i * 8))
|
dest.setFloat64(i * 8, src.getFloat64(i * 8))
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = min_size - min_size % 8; i < min_size; i++) {
|
for (let i = min_size - (min_size % 8); i < min_size; i++) {
|
||||||
dest.setInt8(i, src.getInt8(i))
|
dest.setInt8(i, src.getInt8(i))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
types/ConstArray.d.ts
vendored
12
types/ConstArray.d.ts
vendored
@ -1,8 +1,8 @@
|
|||||||
import { Type } from ".";
|
import { Type } from '.'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructs type of array with constant byte size
|
* constructs type of array with constant byte size
|
||||||
* @param {number} size number of items
|
* @param {number} size number of items
|
||||||
* @returns {Type}
|
* @returns {Type}
|
||||||
*/
|
*/
|
||||||
export function ConstArray(size: number): Type;
|
export function ConstArray(size: number): Type
|
||||||
|
|||||||
12
types/ConstDataView.d.ts
vendored
12
types/ConstDataView.d.ts
vendored
@ -1,8 +1,8 @@
|
|||||||
import { Type } from ".";
|
import { Type } from '.'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructs type of data view with constant byte size
|
* constructs type of data view with constant byte size
|
||||||
* @param {number} byte_size max byte size
|
* @param {number} byte_size max byte size
|
||||||
* @returns {Type}
|
* @returns {Type}
|
||||||
*/
|
*/
|
||||||
export function ConstDataView(byte_size: number): Type;
|
export function ConstDataView(byte_size: number): Type
|
||||||
|
|||||||
12
types/ConstString.d.ts
vendored
12
types/ConstString.d.ts
vendored
@ -1,8 +1,8 @@
|
|||||||
import { Type } from ".";
|
import { Type } from '.'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructs type of utf8-string with constant byte size
|
* constructs type of utf8-string with constant byte size
|
||||||
* @param {number} byte_size max utf8-encoded byte size
|
* @param {number} byte_size max utf8-encoded byte size
|
||||||
* @returns {Type}
|
* @returns {Type}
|
||||||
*/
|
*/
|
||||||
export function ConstString(byte_size: number): Type;
|
export function ConstString(byte_size: number): Type
|
||||||
|
|||||||
4
types/Int.d.ts
vendored
4
types/Int.d.ts
vendored
@ -1,3 +1,3 @@
|
|||||||
import { Type } from ".";
|
import { Type } from '.'
|
||||||
|
|
||||||
export function Int(bits: 8 | 16 | 32, sign: 'signed' | 'unsigned'): Type;
|
export function Int(bits: 8 | 16 | 32, sign: 'signed' | 'unsigned'): Type
|
||||||
|
|||||||
12
types/Struct.d.ts
vendored
12
types/Struct.d.ts
vendored
@ -1,7 +1,9 @@
|
|||||||
import { SerializableType, Type } from "."
|
import { SerializableType, Type } from '.'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructs type of c-like structure. if field is headless, inside of structure will be stored u32 offset, outside of structure will be stored value of field
|
* constructs type of c-like structure. if field is headless, inside of structure will be stored u32 offset, outside of structure will be stored value of field
|
||||||
* @returns {Type}
|
* @returns {Type}
|
||||||
*/
|
*/
|
||||||
export function Struct(type_obj: Record<string, SerializableType | SerializableType[]>): Type;
|
export function Struct(
|
||||||
|
type_obj: Record<string, SerializableType | SerializableType[]>,
|
||||||
|
): Type
|
||||||
|
|||||||
105
types/index.d.ts
vendored
105
types/index.d.ts
vendored
@ -1,59 +1,78 @@
|
|||||||
import { memcpy } from "./mem";
|
import { memcpy } from './mem'
|
||||||
import { limits } from "./limits";
|
import { limits } from './limits'
|
||||||
import { Type } from "./Type"
|
import { Type } from './Type'
|
||||||
import { Int } from "./Int"
|
import { Int } from './Int'
|
||||||
import { ConstString } from "./ConstString"
|
import { ConstString } from './ConstString'
|
||||||
import { ConstArray } from "./ConstArray";
|
import { ConstArray } from './ConstArray'
|
||||||
import { ConstDataView } from "./ConstDataView";
|
import { ConstDataView } from './ConstDataView'
|
||||||
import { Struct } from "./Struct";
|
import { Struct } from './Struct'
|
||||||
|
|
||||||
export { memcpy, limits, Type, Int, ConstString, ConstArray, ConstDataView, Struct }
|
export {
|
||||||
|
memcpy,
|
||||||
|
limits,
|
||||||
|
Type,
|
||||||
|
Int,
|
||||||
|
ConstString,
|
||||||
|
ConstArray,
|
||||||
|
ConstDataView,
|
||||||
|
Struct,
|
||||||
|
}
|
||||||
|
|
||||||
export type SerializableType = BooleanConstructor | NumberConstructor | StringConstructor | ArrayConstructor | DataViewConstructor | Type
|
export type SerializableType =
|
||||||
|
| BooleanConstructor
|
||||||
|
| NumberConstructor
|
||||||
|
| StringConstructor
|
||||||
|
| ArrayConstructor
|
||||||
|
| DataViewConstructor
|
||||||
|
| Type
|
||||||
export type Serializable = unknown
|
export type Serializable = unknown
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {DataView} dv destination memory
|
* @param {DataView} dv destination memory
|
||||||
* @param {Serializable} src source object
|
* @param {Serializable} src source object
|
||||||
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
||||||
* @throws {Error} if too small buffer
|
* @throws {Error} if too small buffer
|
||||||
* @throws {Error} if array|string|DataView size is higher than limits.u32.MAX_VALUE
|
* @throws {Error} if array|string|DataView size is higher than limits.u32.MAX_VALUE
|
||||||
*/
|
*/
|
||||||
export function serialize(dv: DataView, src: Serializable, ...types: SerializableType[]): void;
|
export function serialize(
|
||||||
|
dv: DataView,
|
||||||
|
src: Serializable,
|
||||||
|
...types: SerializableType[]
|
||||||
|
): void
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {DataView} dv source memory
|
* @param {DataView} dv source memory
|
||||||
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
||||||
* @returns {Serializable} parsed object
|
* @returns {Serializable} parsed object
|
||||||
*/
|
*/
|
||||||
export function parse(dv: DataView, ...types: SerializableType[]): Serializable;
|
export function parse(dv: DataView, ...types: SerializableType[]): Serializable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* some types, like Array, String, has no fixed size. So in Structure they are stored as u32 offset, which points to their beginning
|
* some types, like Array, String, has no fixed size. So in Structure they are stored as u32 offset, which points to their beginning
|
||||||
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function isHeadless(...types: SerializableType[]): boolean;
|
export function isHeadless(...types: SerializableType[]): boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if obj has no fixed size, return 4 (sizeof u32 offset)
|
* if obj has no fixed size, return 4 (sizeof u32 offset)
|
||||||
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
export function sizeofHead(...types: SerializableType[]): number;
|
export function sizeofHead(...types: SerializableType[]): number
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Serializable} obj to check
|
* @param {Serializable} obj to check
|
||||||
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
export function sizeof(obj: Serializable, ...types: SerializableType[]): number;
|
export function sizeof(obj: Serializable, ...types: SerializableType[]): number
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
* @param {SerializableType[]} ...types primary and inner types. eg: Array, Number
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
* @throws {Error} if passed Array, String, DataView type (unknown sizeof)
|
* @throws {Error} if passed Array, String, DataView type (unknown sizeof)
|
||||||
*/
|
*/
|
||||||
export function sizeof(...types: SerializableType[]): number;
|
export function sizeof(...types: SerializableType[]): number
|
||||||
|
|
||||||
export function isSerializableType(type: unknown): boolean;
|
export function isSerializableType(type: unknown): boolean
|
||||||
|
|||||||
2
types/limits.d.ts
vendored
2
types/limits.d.ts
vendored
@ -29,4 +29,4 @@ export const limits: {
|
|||||||
bool: IntLimit
|
bool: IntLimit
|
||||||
f32: FloatLimit
|
f32: FloatLimit
|
||||||
f64: FloatLimit
|
f64: FloatLimit
|
||||||
};
|
}
|
||||||
|
|||||||
6
types/mem.d.ts
vendored
6
types/mem.d.ts
vendored
@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* copies max possible number of bytes from src to dest (min of both sizes)
|
* copies max possible number of bytes from src to dest (min of both sizes)
|
||||||
*/
|
*/
|
||||||
export function memcpy(dest: DataView, src: DataView): void;
|
export function memcpy(dest: DataView, src: DataView): void
|
||||||
|
|||||||
Reference in New Issue
Block a user