feat(DataView, ConstDataView)

This commit is contained in:
2025-08-04 15:33:12 +03:00
parent 72f6102f0c
commit 504bfbeae8
11 changed files with 179 additions and 37 deletions

View File

@ -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)
}