feat(Int)
This commit is contained in:
87
src/Int.js
Normal file
87
src/Int.js
Normal file
@ -0,0 +1,87 @@
|
||||
import { Type, limits } from '.'
|
||||
|
||||
export function Int(bits, sign) {
|
||||
const obj = { _size: bits / 8 }
|
||||
Object.setPrototypeOf(obj, Int.prototype)
|
||||
obj.new(Int, arguments)
|
||||
|
||||
switch (sign) {
|
||||
case 'signed':
|
||||
switch (bits) {
|
||||
case 8:
|
||||
obj._dv_set = DataView.prototype.setInt8
|
||||
obj._dv_get = DataView.prototype.getInt8
|
||||
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('incorrect bits ' + bits)
|
||||
}
|
||||
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('incorrect bits ' + bits)
|
||||
}
|
||||
break
|
||||
|
||||
default:
|
||||
throw new Error('incorrect sign ' + sign)
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
Int.prototype.serialize = function (dv, src) {
|
||||
if (dv.byteLength < this._size) {
|
||||
throw new Error('buffer is too small')
|
||||
}
|
||||
if (src > this._limits.MAX_VALUE) {
|
||||
throw new Error(`number should be less or equal than ` + this._limits.MAX_VALUE)
|
||||
}
|
||||
if (src < this._limits.MIN_VALUE) {
|
||||
throw new Error(`number should be more or equal than ` + this._limits.MIN_VALUE)
|
||||
}
|
||||
this._dv_set.call(dv, 0, src)
|
||||
}
|
||||
Int.prototype.parse = function (dv) {
|
||||
return this._dv_get.call(dv, 0)
|
||||
}
|
||||
Int.prototype.isHeadless = function () {
|
||||
return false
|
||||
}
|
||||
Int.prototype.sizeof = function () {
|
||||
return this._size
|
||||
}
|
||||
Object.setPrototypeOf(Int.prototype, Type.prototype)
|
||||
Object.freeze(Int.prototype)
|
||||
@ -1,12 +1,13 @@
|
||||
import { limits } from "./limits"
|
||||
import { memcpy } from "./mem"
|
||||
import { Type } from "./Type"
|
||||
import { Int } from "./Int"
|
||||
import { ConstString } from './ConstString'
|
||||
import { ConstArray } from "./ConstArray"
|
||||
import { ConstDataView } from './ConstDataView'
|
||||
import { Struct } from './Struct'
|
||||
|
||||
export { limits, memcpy, Type, ConstString, ConstArray, ConstDataView, Struct }
|
||||
export { limits, memcpy, Type, Int, ConstString, ConstArray, ConstDataView, Struct }
|
||||
|
||||
export function serialize(dv, src, ...types) {
|
||||
const [type, ...inner_types] = types
|
||||
|
||||
29
test/Int.test.js
Normal file
29
test/Int.test.js
Normal file
@ -0,0 +1,29 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { expectDataViewEqual, filledDataView, sizedDataView } from '.';
|
||||
import { Int, parse, serialize, sizeof } from "../src";
|
||||
|
||||
describe(Int.name, () => {
|
||||
|
||||
const Type = Int(32, 'unsigned')
|
||||
const type = 512
|
||||
const type_dv = filledDataView([0x00, 0x00, 0x02, 0x00])
|
||||
|
||||
test('serialize', () => {
|
||||
let actual = sizedDataView(3);
|
||||
expect(() => serialize(actual, type, Type)).toThrow()
|
||||
|
||||
actual = sizedDataView(sizeof(Type))
|
||||
serialize(actual, type, Type)
|
||||
|
||||
expectDataViewEqual(actual, type_dv)
|
||||
})
|
||||
|
||||
test('parse', () => {
|
||||
expect(parse(type_dv, Type)).toEqual(type)
|
||||
})
|
||||
|
||||
test('serialize, overflow', () => {
|
||||
expect(() => serialize(sizedDataView(1), 128, Int(8, 'signed'))).toThrow()
|
||||
expect(() => serialize(sizedDataView(1), -129, Int(8, 'signed'))).toThrow()
|
||||
})
|
||||
})
|
||||
3
types/Int.d.ts
vendored
Normal file
3
types/Int.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import { Type } from ".";
|
||||
|
||||
export function Int(bits: 8 | 16 | 32, sign: 'signed' | 'unsigned'): Type;
|
||||
3
types/index.d.ts
vendored
3
types/index.d.ts
vendored
@ -1,12 +1,13 @@
|
||||
import { memcpy } from "./mem";
|
||||
import { limits } from "./limits";
|
||||
import { Type } from "./Type"
|
||||
import { Int } from "./Int"
|
||||
import { ConstString } from "./ConstString"
|
||||
import { ConstArray } from "./ConstArray";
|
||||
import { ConstDataView } from "./ConstDataView";
|
||||
import { Struct } from "./Struct";
|
||||
|
||||
export { memcpy, limits, Type, ConstString, ConstArray, ConstDataView, Struct }
|
||||
export { memcpy, limits, Type, Int, ConstString, ConstArray, ConstDataView, Struct }
|
||||
|
||||
export type SerializableType = NumberConstructor | StringConstructor | ArrayConstructor | DataViewConstructor | Type
|
||||
export type Serializable = unknown
|
||||
|
||||
Reference in New Issue
Block a user