feat(DataView, ConstDataView)
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { limits, parse, serialize, sizeofHead, Type } from "."
|
||||
import { parse, serialize, sizeofHead, Type } from "."
|
||||
|
||||
export function ConstArray(size) {
|
||||
const obj = { _size: size }
|
||||
@ -8,16 +8,11 @@ export function ConstArray(size) {
|
||||
}
|
||||
ConstArray.prototype.serialize = function(dv, src, ...inner_types) {
|
||||
const item_size = sizeofHead(src[0])
|
||||
let size = this._size
|
||||
const size = this._size
|
||||
|
||||
if (dv.byteLength < size * item_size) {
|
||||
throw new Error('too small buffer')
|
||||
}
|
||||
if (size > limits.u32.MAX_VALUE) {
|
||||
throw new Error('array is too long')
|
||||
}
|
||||
|
||||
dv.setUint32(0, size)
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
const item_frame = new DataView(dv.buffer, dv.byteOffset + item_size * i)
|
||||
|
||||
31
src/ConstDataView.js
Normal file
31
src/ConstDataView.js
Normal file
@ -0,0 +1,31 @@
|
||||
import { memcpy, Type } from "."
|
||||
|
||||
export function ConstDataView(size) {
|
||||
const obj = { _size: size }
|
||||
Object.setPrototypeOf(obj, ConstDataView.prototype)
|
||||
obj.new(ConstDataView, arguments)
|
||||
return obj
|
||||
}
|
||||
ConstDataView.prototype.serialize = function(dv, src) {
|
||||
if (dv.byteLength < this._size) {
|
||||
throw new Error('too small buffer')
|
||||
}
|
||||
memcpy(dv, src)
|
||||
return
|
||||
}
|
||||
ConstDataView.prototype.parse = function(dv) {
|
||||
const res_buffer = new ArrayBuffer(this._size)
|
||||
const res_dv = new DataView(res_buffer)
|
||||
|
||||
memcpy(res_dv, dv)
|
||||
|
||||
return res_dv
|
||||
}
|
||||
ConstDataView.prototype.isHeadless = function() {
|
||||
return false
|
||||
}
|
||||
ConstDataView.prototype.sizeof = function() {
|
||||
return this._size
|
||||
}
|
||||
Object.setPrototypeOf(ConstDataView.prototype, Type.prototype)
|
||||
Object.freeze(ConstDataView.prototype)
|
||||
35
src/index.js
35
src/index.js
@ -2,10 +2,11 @@ import { limits } from "./limits"
|
||||
import { memcpy } from "./mem"
|
||||
import { Type } from "./Type"
|
||||
import { ConstString } from './ConstString'
|
||||
import { ConstArray } from "./ConstArray"
|
||||
import { ConstArray } from "./ConstArray"
|
||||
import { ConstDataView } from './ConstDataView'
|
||||
import { Struct } from './Struct'
|
||||
|
||||
export { limits, memcpy, Type, ConstString, ConstArray, Struct }
|
||||
export { limits, memcpy, Type, ConstString, ConstArray, ConstDataView, Struct }
|
||||
|
||||
export function serialize(dv, src, ...types) {
|
||||
const [type, ...inner_types] = types
|
||||
@ -54,6 +55,19 @@ export function serialize(dv, src, ...types) {
|
||||
}
|
||||
return
|
||||
}
|
||||
if (type == DataView && src instanceof DataView) {
|
||||
if (dv.byteLength < 4 + src.byteLength) {
|
||||
throw new Error('too small buffer')
|
||||
}
|
||||
if (src.byteLength > limits.u32.MAX_VALUE) {
|
||||
throw new Error('data view is too long')
|
||||
}
|
||||
|
||||
dv.setUint32(0, src.byteLength)
|
||||
|
||||
const frame = new DataView(dv.buffer, dv.byteOffset + 4)
|
||||
memcpy(frame, src)
|
||||
}
|
||||
if (type instanceof Type) {
|
||||
type.serialize(dv, src, ...inner_types)
|
||||
return
|
||||
@ -84,6 +98,16 @@ export function parse(dv, ...types) {
|
||||
|
||||
return array
|
||||
}
|
||||
if (type == DataView) {
|
||||
const size = dv.getUint32(0)
|
||||
const res_buffer = new ArrayBuffer(size)
|
||||
const res_dv = new DataView(res_buffer)
|
||||
|
||||
const frame = new DataView(dv.buffer, dv.byteOffset + 4)
|
||||
memcpy(res_dv, frame)
|
||||
|
||||
return res_dv
|
||||
}
|
||||
if (type instanceof Type) {
|
||||
return type.parse(dv, ...inner_types)
|
||||
}
|
||||
@ -96,8 +120,10 @@ export function isHeadless(...args) {
|
||||
}
|
||||
return arg == Array ||
|
||||
arg == String ||
|
||||
arg == DataView ||
|
||||
Array.isArray(arg) ||
|
||||
typeof arg == 'string'
|
||||
typeof arg == 'string' ||
|
||||
arg instanceof DataView
|
||||
}
|
||||
|
||||
export function sizeofHead(...args) {
|
||||
@ -121,6 +147,9 @@ export function sizeof(...args) {
|
||||
if (Array.isArray(arg)) {
|
||||
return 4 + sizeofHead(arg[0]) * arg.length
|
||||
}
|
||||
if (arg instanceof DataView) {
|
||||
return 4 + arg.byteLength
|
||||
}
|
||||
if (arg instanceof Type) {
|
||||
return arg.sizeof(...inner_args)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user