structurae
Advanced tools
Comparing version 1.7.1 to 1.7.2
@@ -7,3 +7,10 @@ # Changelog | ||
## [1.7.1] - 2019-11-09 | ||
## [1.7.2] - 2019-09-13 | ||
## Added | ||
- StringView.from uses TextEncoder#encodeInto | ||
## Changed | ||
- ArrayView supports strings and replaces StringArrayView | ||
## [1.7.1] - 2019-09-11 | ||
### Added | ||
@@ -10,0 +17,0 @@ - Support custom types in nested ObjectViews |
@@ -211,4 +211,10 @@ // Type definitions for structurae | ||
type ViewType = typeof ArrayView | typeof ObjectView | typeof TypedArrayView | typeof StringView | typeof StringArrayView; | ||
type View = ObjectView | ArrayView | TypedArrayView | StringView | StringArrayView; | ||
declare class ArrayView extends DataView { | ||
size: number; | ||
static itemLength: number; | ||
static View: typeof ObjectView | typeof StringView; | ||
@@ -227,8 +233,5 @@ get(index: number): ObjectView; | ||
export declare function ArrayViewMixin<T extends ObjectView>(Base: Constructor<T>): Constructor<T & ArrayView> | ||
export declare function ArrayViewMixin(ObjectViewClass: typeof ObjectView | typeof StringView, | ||
itemLength?: number): typeof ArrayView; | ||
type ViewType = typeof ArrayView | typeof ObjectView | typeof TypedArrayView | typeof StringView | typeof StringArrayView; | ||
type View = ObjectView | ArrayView | TypedArrayView | StringView | StringArrayView; | ||
type PrimitiveFieldType = 'int8' | 'uint8' | 'int16' | 'uint16' | ||
@@ -262,13 +265,7 @@ | 'int32' | 'uint32' | 'float32' | 'float64' | 'bigint64' | 'biguint64'; | ||
get(field: string): number | View; | ||
private getArray(position: number, field: ObjectViewField): ArrayLike<object>; | ||
private getObject(position: number, field: ObjectViewField): object; | ||
private getString(position: number, field: ObjectViewField): string; | ||
private getStringArray(position: number, field: ObjectViewField): string[]; | ||
private getTypedArray(position: number, field: ObjectViewField): ArrayLike<number>; | ||
getValue(field: string): any; | ||
set(field: string, value: any): this; | ||
private setArray(position: number, value: ArrayLike<object>, field: ObjectViewField): void; | ||
private setObject(position: number, value: object, field: ObjectViewField): void; | ||
private setString(position: number, value: string, field: ObjectViewField): void; | ||
private setStringArray(position: number, value: string[], field: ObjectViewField): void; | ||
private setTypedArray(position: number, value: ArrayLike<number>, field: ObjectViewField): void; | ||
@@ -305,2 +302,3 @@ setView(field: string, value: View): this; | ||
static fromString(string: string, size?: number): StringView; | ||
static from(arrayLike: ArrayLike<number>|string, mapFn?: Function | StringView): StringView; | ||
static getByteSize(string: string): number; | ||
@@ -328,6 +326,6 @@ } | ||
size: number; | ||
private static typeGetter: string; | ||
private static typeSetter: string; | ||
private static offset: number; | ||
private static littleEndian: boolean; | ||
static typeGetter: string; | ||
static typeSetter: string; | ||
static offset: number; | ||
static littleEndian: boolean; | ||
@@ -344,3 +342,3 @@ get(index: number): number; | ||
export declare function TypedArrayViewMixin(type: PrimitiveFieldType, littleEndian: boolean): TypedArrayView; | ||
export declare function TypedArrayViewMixin(type: PrimitiveFieldType, littleEndian: boolean): typeof TypedArrayView; | ||
@@ -347,0 +345,0 @@ export declare class CollectionView extends DataView { |
/** | ||
* @param {Class<ObjectView>} ObjectViewClass | ||
* @returns {Class<ArrayView>} | ||
* An array of ObjectViews. Uses DataView to operate on an array of JavaScript objects | ||
* stored in an ArrayBuffer. | ||
* | ||
* @extends DataView | ||
*/ | ||
function ArrayViewMixin(ObjectViewClass) { | ||
if (!ObjectViewClass.isInitialized) ObjectViewClass.initialize(); | ||
class ArrayView extends DataView { | ||
/** | ||
* Returns an object view at a given index. | ||
* | ||
* @param {number} index | ||
* @returns {ObjectView} | ||
*/ | ||
get(index) { | ||
const { itemLength, View } = this.constructor; | ||
return new View( | ||
this.buffer, this.byteOffset + (index * itemLength), itemLength, | ||
); | ||
} | ||
/** | ||
* @extends ObjectView | ||
* Returns an object at a given index. | ||
* | ||
* @param {number} index | ||
* @returns {Object} | ||
*/ | ||
class ArrayView extends DataView { | ||
/** | ||
* Returns an object view at a given index. | ||
* | ||
* @param {number} index | ||
* @returns {ObjectView} | ||
*/ | ||
get(index) { | ||
const { objectLength } = this.constructor; | ||
return new ObjectViewClass( | ||
this.buffer, this.byteOffset + (index * objectLength), objectLength, | ||
); | ||
} | ||
getValue(index) { | ||
return this.get(index).toJSON(); | ||
} | ||
/** | ||
* Returns an object at a given index. | ||
* | ||
* @param {number} index | ||
* @returns {Object} | ||
*/ | ||
getValue(index) { | ||
return this.get(index).toJSON(); | ||
} | ||
/** | ||
* Sets an object at a given index. | ||
* | ||
* @param {number} index | ||
* @param {Object} value | ||
* @returns {ArrayView} | ||
*/ | ||
set(index, value) { | ||
this.constructor.View.from(value, this.get(index)); | ||
return this; | ||
} | ||
/** | ||
* Sets an object at a given index. | ||
* | ||
* @param {number} index | ||
* @param {Object} value | ||
* @returns {ArrayView} | ||
*/ | ||
set(index, value) { | ||
ObjectViewClass.from(value, this.get(index)); | ||
return this; | ||
} | ||
/** | ||
* Sets an object view at a given index. | ||
* | ||
* @param {number} index | ||
* @param {ObjectView} value | ||
* @returns {ArrayView} | ||
*/ | ||
setView(index, value) { | ||
const { itemLength } = this.constructor; | ||
new Uint8Array(this.buffer, this.byteOffset + (index * itemLength), itemLength) | ||
.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength)); | ||
return this; | ||
} | ||
/** | ||
* Sets an object view at a given index. | ||
* | ||
* @param {number} index | ||
* @param {ObjectView} value | ||
* @returns {ArrayView} | ||
*/ | ||
setView(index, value) { | ||
const { objectLength } = this.constructor; | ||
new Uint8Array(this.buffer, this.byteOffset + (index * objectLength), objectLength) | ||
.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength)); | ||
return this; | ||
} | ||
/** | ||
* Returns the amount of available objects in the array. | ||
* | ||
* @type {number} | ||
*/ | ||
get size() { | ||
return this.byteLength / this.constructor.itemLength; | ||
} | ||
/** | ||
* Returns the amount of available objects in the array. | ||
* | ||
* @type {number} | ||
*/ | ||
get size() { | ||
return this.byteLength / this.constructor.objectLength; | ||
} | ||
/** | ||
* Allows iterating over objects stored in the array. | ||
* | ||
* @returns {Iterable<ObjectView>} | ||
*/ | ||
* [Symbol.iterator]() { | ||
const { size } = this; | ||
for (let i = 0; i < size; i++) { | ||
yield this.get(i); | ||
} | ||
/** | ||
* Allows iterating over objects views stored in the array. | ||
* | ||
* @returns {Iterable<ObjectView>} | ||
*/ | ||
* [Symbol.iterator]() { | ||
const { size } = this; | ||
for (let i = 0; i < size; i++) { | ||
yield this.get(i); | ||
} | ||
} | ||
/** | ||
* @deprecated use `ArrayView#toJSON()` instead. | ||
* Returns an array representation of the array view. | ||
* | ||
* @returns {Array<Object>} | ||
*/ | ||
toObject() { | ||
return this.toJSON(); | ||
} | ||
/** | ||
* @deprecated use `ArrayView#toJSON()` instead. | ||
* Returns an array representation of the array view. | ||
* | ||
* @returns {Array<Object>} | ||
*/ | ||
toObject() { | ||
return this.toJSON(); | ||
} | ||
/** | ||
* Returns an array representation of the array view. | ||
* | ||
* @returns {Array<Object>} | ||
*/ | ||
toJSON() { | ||
const { size } = this; | ||
const json = new Array(size); | ||
for (let i = 0; i < size; i++) { | ||
json[i] = this.get(i).toJSON(); | ||
} | ||
return json; | ||
/** | ||
* Returns an array representation of the array view. | ||
* | ||
* @returns {Array<Object>} | ||
*/ | ||
toJSON() { | ||
const { size } = this; | ||
const json = new Array(size); | ||
for (let i = 0; i < size; i++) { | ||
json[i] = this.get(i).toJSON(); | ||
} | ||
return json; | ||
} | ||
/** | ||
* Creates an array view from a given array of objects. | ||
* | ||
* @param {ArrayLike<Object>} value | ||
* @param {ArrayView} [array] | ||
* @returns {ArrayView} | ||
*/ | ||
static from(value, array) { | ||
const arrayView = array || this.of(value.length); | ||
const { size } = arrayView; | ||
for (let i = 0; i < size; i++) { | ||
arrayView.set(i, value[i]); | ||
} | ||
return arrayView; | ||
/** | ||
* Creates an array view from a given array of objects. | ||
* | ||
* @param {ArrayLike<Object>} value | ||
* @param {ArrayView} [array] | ||
* @returns {ArrayView} | ||
*/ | ||
static from(value, array) { | ||
const view = array || this.of(value.length); | ||
if (array) { | ||
new Uint8Array(view.buffer, view.byteOffset, view.byteLength).fill(0); | ||
} | ||
/** | ||
* Returns the byte length of an array view to hold a given amount of objects. | ||
* | ||
* @param {number} size | ||
* @returns {number} | ||
*/ | ||
static getLength(size) { | ||
return size * this.objectLength; | ||
const { size } = view; | ||
const max = (size < value.length ? size : value.length); | ||
for (let i = 0; i < max; i++) { | ||
view.set(i, value[i]); | ||
} | ||
return view; | ||
} | ||
/** | ||
* Creates an empty array view of specified size. | ||
* | ||
* @param {number} size | ||
* @returns {ArrayView} | ||
*/ | ||
static of(size = 1) { | ||
const buffer = new ArrayBuffer(this.getLength(size)); | ||
return new this(buffer); | ||
} | ||
/** | ||
* Returns the byte length of an array view to hold a given amount of objects. | ||
* | ||
* @param {number} size | ||
* @returns {number} | ||
*/ | ||
static getLength(size) { | ||
return size * this.itemLength; | ||
} | ||
/** | ||
* @private | ||
* Creates an empty array view of specified size. | ||
* | ||
* @param {number} size | ||
* @returns {ArrayView} | ||
*/ | ||
ArrayView.objectLength = ObjectViewClass.objectLength; | ||
static of(size = 1) { | ||
const buffer = new ArrayBuffer(this.getLength(size)); | ||
return new this(buffer); | ||
} | ||
} | ||
return ArrayView; | ||
/** | ||
* @type {number} | ||
*/ | ||
ArrayView.itemLength = 0; | ||
/** | ||
* @type {ObjectView} | ||
*/ | ||
ArrayView.View = undefined; | ||
/** | ||
* @param {Class<ObjectView>|Class<StringView>} ObjectViewClass | ||
* @param {number} [itemLength] | ||
* @returns {Class<ArrayView>} | ||
*/ | ||
function ArrayViewMixin(ObjectViewClass, itemLength) { | ||
if (ObjectViewClass.initialize && !ObjectViewClass.isInitialized) { | ||
ObjectViewClass.initialize(); | ||
} | ||
class Base extends ArrayView {} | ||
Base.View = ObjectViewClass; | ||
Base.itemLength = ObjectViewClass.objectLength || itemLength; | ||
return Base; | ||
} | ||
@@ -152,0 +169,0 @@ |
@@ -22,3 +22,3 @@ /** | ||
/** | ||
* Sets . | ||
* Sets an object at a given index. | ||
* | ||
@@ -140,4 +140,7 @@ * @param {number} index | ||
/** | ||
* @type {Array<ViewType>} | ||
*/ | ||
CollectionView.schema = []; | ||
module.exports = CollectionView; |
const StringView = require('./string-view'); | ||
const StringArrayView = require('./string-array-view'); | ||
const ArrayViewMixin = require('./array-view'); | ||
@@ -8,6 +7,19 @@ const TypedArrayViewMixin = require('./typed-array-view'); | ||
/** | ||
* @typedef {(string|Class<ObjectView>)} ObjectViewFieldType | ||
* @typedef {Class<ArrayView>|Class<ObjectView>|Class<TypedArrayView>|Class<StringView>} ViewType | ||
*/ | ||
/** | ||
* @typedef {ArrayView|ObjectView|TypedArrayView|StringView} View | ||
*/ | ||
/** | ||
* @typedef {'int8'|'uint8'|'int16'|'uint16'|'int32' | ||
* |'uint32'|'float32'|'float64'|'bigint64'|'biguint64'} PrimitiveFieldType | ||
*/ | ||
/** | ||
* @typedef {(PrimitiveFieldType|string|ViewType)} ObjectViewFieldType | ||
*/ | ||
/** | ||
* @typedef {Object} ObjectViewField | ||
@@ -19,4 +31,3 @@ * @property {ObjectViewFieldType} type | ||
* @property {number} [start] | ||
* @property {Class<ArrayView>|Class<ObjectView>|Class<TypedArrayView> | ||
* |Class<StringView>|Class<StringArrayView>} [View] | ||
* @property {ViewType} [View] | ||
* @property {string} [getter] | ||
@@ -28,2 +39,4 @@ * @property {string} [setter] | ||
/** | ||
* A DataView based C-like struct to store JavaScript objects in ArrayBuffer. | ||
* | ||
* @extends DataView | ||
@@ -40,6 +53,6 @@ */ | ||
const { | ||
getter, start, kind, littleEndian, View, length, itemLength, | ||
getter, start, kind, littleEndian, View, length, | ||
} = this.constructor.schema[field]; | ||
if (kind === 'number') return this[getter](start, littleEndian); | ||
return new View(this.buffer, this.byteOffset + start, length, itemLength); | ||
return new View(this.buffer, this.byteOffset + start, length); | ||
} | ||
@@ -51,18 +64,2 @@ | ||
* @param {ObjectViewField} field | ||
* @returns {Array<Object>} | ||
*/ | ||
getArray(position, field) { | ||
const { size, type: View, itemLength } = field; | ||
const json = new Array(size); | ||
for (let i = 0; i < size; i++) { | ||
const view = new View(this.buffer, this.byteOffset + position + (i * itemLength), itemLength); | ||
json[i] = view.toJSON(); | ||
} | ||
return json; | ||
} | ||
/** | ||
* @private | ||
* @param {number} position | ||
* @param {ObjectViewField} field | ||
* @returns {Object} | ||
@@ -80,30 +77,2 @@ */ | ||
* @param {ObjectViewField} field | ||
* @returns {string} | ||
*/ | ||
getString(position, field) { | ||
return new StringView(this.buffer, this.byteOffset + position, field.length).toString(); | ||
} | ||
/** | ||
* @private | ||
* @param {number} position | ||
* @param {ObjectViewField} field | ||
* @returns {Array<string>} | ||
*/ | ||
getStringArray(position, field) { | ||
const { size, itemLength } = field; | ||
const array = new Array(size); | ||
for (let i = 0; i < size; i++) { | ||
const string = new StringView( | ||
this.buffer, this.byteOffset + position + (i * itemLength), itemLength, | ||
); | ||
array[i] = string.toString(); | ||
} | ||
return array; | ||
} | ||
/** | ||
* @private | ||
* @param {number} position | ||
* @param {ObjectViewField} field | ||
* @returns {Array<number>} | ||
@@ -135,3 +104,3 @@ */ | ||
/** | ||
* Sets a value to a field. | ||
* Sets a JavaScript value to a field. | ||
* | ||
@@ -155,18 +124,2 @@ * @param {string} field the name of the field | ||
* @param {number} position | ||
* @param {ArrayLike<object>} value | ||
* @param {ObjectViewField} field | ||
* @returns {void} | ||
*/ | ||
setArray(position, value, field) { | ||
const { size, type: View, itemLength } = field; | ||
const max = (size < value.length ? size : value.length); | ||
for (let i = 0; i < max; i++) { | ||
const view = new View(this.buffer, this.byteOffset + position + (i * itemLength), itemLength); | ||
View.from(value[i], view); | ||
} | ||
} | ||
/** | ||
* @private | ||
* @param {number} position | ||
* @param {Object} value | ||
@@ -185,33 +138,2 @@ * @param {ObjectViewField} field | ||
* @param {number} position | ||
* @param {string} value | ||
* @param {ObjectViewField} field | ||
* @returns {void} | ||
*/ | ||
setString(position, value, field) { | ||
new Uint8Array(this.buffer, this.byteOffset + position, field.length) | ||
.fill(0) | ||
.set(StringView.fromString(value)); | ||
} | ||
/** | ||
* @private | ||
* @param {number} position | ||
* @param {string} value | ||
* @param {ObjectViewField} field | ||
* @returns {void} | ||
*/ | ||
setStringArray(position, value, field) { | ||
const { length, size, itemLength } = field; | ||
const array = new Uint8Array(this.buffer, this.byteOffset + position, length); | ||
array.fill(0); | ||
const max = (size < value.length ? size : value.length); | ||
for (let i = 0; i < max; i++) { | ||
const string = StringView.fromString(value[i], itemLength); | ||
array.set(string, i * itemLength); | ||
} | ||
} | ||
/** | ||
* @private | ||
* @param {number} position | ||
* @param {ArrayLike<number>} value | ||
@@ -222,4 +144,6 @@ * @param {ObjectViewField} field | ||
setTypedArray(position, value, field) { | ||
const { View, size } = field; | ||
const { View, size, length } = field; | ||
const { typeSetter, offset, littleEndian } = View; | ||
new Uint8Array(this.buffer, this.byteOffset + position, length) | ||
.fill(0); | ||
const max = (size < value.length ? size : value.length); | ||
@@ -232,6 +156,6 @@ for (let i = 0; i < max; i++) { | ||
/** | ||
* Sets an ObjectView value to a field. | ||
* Sets an View to a field. | ||
* | ||
* @param {string} field the name of the field | ||
* @param {ObjectView|ArrayView|TypedArrayView|StringView} value the view to set | ||
* @param {View} value the view to set | ||
* @returns {ObjectView} | ||
@@ -260,3 +184,3 @@ */ | ||
/** | ||
* Returns an Object corresponding to the object view. | ||
* Returns an Object corresponding to the view. | ||
* | ||
@@ -276,4 +200,3 @@ * @returns {Object} | ||
/** | ||
* Assigns fields of a given object to the provided object view | ||
* or a new object view. | ||
* Assigns fields of a given object to the provided view or a new object view. | ||
* | ||
@@ -286,2 +209,7 @@ * @param {Object} object the object to take data from | ||
const objectView = view || new this(new ArrayBuffer(this.getLength())); | ||
if (view) { | ||
// zero out existing view | ||
new Uint8Array(objectView.buffer, objectView.byteOffset, objectView.byteLength) | ||
.fill(0); | ||
} | ||
const { fields } = objectView.constructor; | ||
@@ -306,2 +234,4 @@ for (let i = 0; i < fields.length; i++) { | ||
/** | ||
* Initializes the object view class. | ||
* | ||
* @returns {void} | ||
@@ -352,3 +282,3 @@ */ | ||
case 'string': | ||
if (size) return 'stringarray'; | ||
if (size) return 'array'; | ||
return 'string'; | ||
@@ -391,4 +321,4 @@ default: | ||
field.View = StringView; | ||
field.getter = 'getString'; | ||
field.setter = 'setString'; | ||
field.getter = 'getObject'; | ||
field.setter = 'setObject'; | ||
}, | ||
@@ -399,14 +329,2 @@ /** | ||
*/ | ||
stringarray(field) { | ||
const { length, size } = field; | ||
field.View = StringArrayView; | ||
field.length = StringArrayView.getLength(size, length); | ||
field.getter = 'getStringArray'; | ||
field.setter = 'setStringArray'; | ||
field.itemLength = length; | ||
}, | ||
/** | ||
* @param {ObjectViewField} field | ||
* @returns {void} | ||
*/ | ||
object(field) { | ||
@@ -424,8 +342,8 @@ const { type } = field; | ||
array(field) { | ||
const { type, size } = field; | ||
field.View = ArrayViewMixin(type); | ||
const { type, size, length } = field; | ||
field.View = type === 'string' ? ArrayViewMixin(StringView, length) : ArrayViewMixin(type); | ||
field.length = field.View.getLength(size); | ||
field.getter = 'getArray'; | ||
field.setter = 'setArray'; | ||
field.itemLength = type.objectLength; | ||
field.getter = 'getObject'; | ||
field.setter = 'setObject'; | ||
field.itemLength = field.View.itemLength; | ||
}, | ||
@@ -432,0 +350,0 @@ }; |
const StringView = require('./string-view'); | ||
/** | ||
* @deprecated use ArrayView instead | ||
* An array of StringViews. Uses an ArrayBuffer to hold an array of UTF-8 encoded strings. | ||
@@ -48,4 +49,5 @@ */ | ||
set(index, value) { | ||
const view = StringView.fromString(value, this.stringLength); | ||
this.bytes.set(view, index * this.stringLength); | ||
const view = this.get(index); | ||
view.fill(0); | ||
StringView.from(value, view); | ||
return this; | ||
@@ -124,4 +126,3 @@ } | ||
for (let i = 0; i < size; i++) { | ||
const string = StringView.fromString(value[i], stringLength); | ||
view.bytes.set(string, i * stringLength); | ||
view.set(i, value[i]); | ||
} | ||
@@ -128,0 +129,0 @@ return view; |
@@ -314,2 +314,3 @@ /** | ||
* | ||
* @deprecated use StringView.from instead | ||
* @param {string} string the string to encode | ||
@@ -339,2 +340,18 @@ * @param {number} [size] the size of the StringView in bytes | ||
/** | ||
* Creates a StringView from a string or an array like object. | ||
* | ||
* @param {ArrayLike<number>|string} arrayLike | ||
* @param {Function|Uint8Array|StringView} [mapFn] | ||
* @param {Object} [thisArg] | ||
* @returns {Uint8Array|StringView} | ||
*/ | ||
static from(arrayLike, mapFn, thisArg) { | ||
if (typeof arrayLike !== 'string') return super.from(arrayLike, mapFn, thisArg); | ||
if (!mapFn) return new this(this.encoder.encode(arrayLike).buffer); | ||
mapFn.fill(0); | ||
this.encoder.encodeInto(arrayLike, mapFn); | ||
return mapFn; | ||
} | ||
/** | ||
* Returns the size in bytes of a given string without encoding it. | ||
@@ -380,2 +397,18 @@ * | ||
if (!StringView.encoder.encodeInto) { | ||
/** | ||
* Polyfill for TextEncoder#encodeInto | ||
* @param {string} source | ||
* @param {Uint8Array} destination | ||
* @returns {Uint8Array} | ||
*/ | ||
StringView.encoder.encodeInto = (source, destination) => { | ||
const encoded = StringView.encoder.encode(source); | ||
const trimmed = encoded.length > destination.length | ||
? encoded.subarray(0, destination.length) : encoded; | ||
destination.set(trimmed); | ||
return destination; | ||
}; | ||
} | ||
module.exports = StringView; |
const { typeGetters, typeSetters, typeOffsets } = require('./utilities'); | ||
/** | ||
* @param {string} type | ||
* @param {boolean} [littleEndian] | ||
* @returns {Class<TypedArrayView>} | ||
* A DataView based TypedArray that supports endianness and can be set at any offset. | ||
* | ||
* @extends DataView | ||
*/ | ||
function TypedArrayViewMixin(type, littleEndian) { | ||
class TypedArrayView extends DataView { | ||
/** | ||
* @extends DataView | ||
* Returns a number at a given index. | ||
* | ||
* @param {number} index | ||
* @returns {number} | ||
*/ | ||
class TypedArrayView extends DataView { | ||
/** | ||
* Returns a number at a given index. | ||
* | ||
* @param {number} index | ||
* @returns {number} | ||
*/ | ||
get(index) { | ||
const { typeGetter, offset, littleEndian: le } = this.constructor; | ||
return this[typeGetter](index << offset, le); | ||
} | ||
get(index) { | ||
const { typeGetter, offset, littleEndian: le } = this.constructor; | ||
return this[typeGetter](index << offset, le); | ||
} | ||
/** | ||
* Sets a number at a given index. | ||
* | ||
* @param {number} index | ||
* @param {number} value | ||
* @returns {TypedArrayView} | ||
*/ | ||
set(index, value) { | ||
const { typeSetter, offset, littleEndian: le } = this.constructor; | ||
this[typeSetter](index << offset, value, le); | ||
return this; | ||
} | ||
/** | ||
* Sets a number at a given index. | ||
* | ||
* @param {number} index | ||
* @param {number} value | ||
* @returns {TypedArrayView} | ||
*/ | ||
set(index, value) { | ||
const { typeSetter, offset, littleEndian: le } = this.constructor; | ||
this[typeSetter](index << offset, value, le); | ||
return this; | ||
} | ||
/** | ||
* Returns the amount of available numbers in the array. | ||
* | ||
* @type {number} | ||
*/ | ||
get size() { | ||
return this.byteLength >> this.constructor.offset; | ||
} | ||
/** | ||
* Returns the amount of available numbers in the array. | ||
* | ||
* @type {number} | ||
*/ | ||
get size() { | ||
return this.byteLength >> this.constructor.offset; | ||
} | ||
/** | ||
* Allows iterating over numbers stored in the instance. | ||
* | ||
* @returns {Iterable<number>} | ||
*/ | ||
* [Symbol.iterator]() { | ||
const { size } = this; | ||
for (let i = 0; i < size; i++) { | ||
yield this.get(i); | ||
} | ||
/** | ||
* Allows iterating over numbers stored in the instance. | ||
* | ||
* @returns {Iterable<number>} | ||
*/ | ||
* [Symbol.iterator]() { | ||
const { size } = this; | ||
for (let i = 0; i < size; i++) { | ||
yield this.get(i); | ||
} | ||
} | ||
/** | ||
* @deprecated use `TypedArrayView#toJSON()` instead | ||
* Returns an array representation of the array view. | ||
* | ||
* @returns {Array<number>} | ||
*/ | ||
toObject() { | ||
return this.toJSON(); | ||
} | ||
/** | ||
* Returns an array representation of the array view. | ||
* | ||
* @returns {Array<number>} | ||
*/ | ||
toJSON() { | ||
return [...this]; | ||
} | ||
/** | ||
* Returns the byte length of an array view to hold a given amount of numbers. | ||
* | ||
* @param {number} size | ||
* @returns {number} | ||
*/ | ||
static getLength(size) { | ||
return size << this.offset; | ||
} | ||
/** | ||
* Creates an array view from a given array of numbers. | ||
* | ||
* @param {ArrayLike<number>} value | ||
* @param {TypedArrayView} [array] | ||
* @returns {TypedArrayView} | ||
*/ | ||
static from(value, array) { | ||
const dataArray = array || this.of(value.length); | ||
const { size } = dataArray; | ||
for (let i = 0; i < size; i++) { | ||
dataArray.set(i, value[i]); | ||
} | ||
return dataArray; | ||
} | ||
/** | ||
* Creates an empty array view of specified size. | ||
* | ||
* @param {number} size | ||
* @returns {TypedArrayView} | ||
*/ | ||
static of(size = 1) { | ||
const buffer = new ArrayBuffer(this.getLength(size)); | ||
return new this(buffer); | ||
} | ||
/** | ||
* @deprecated use `TypedArrayView#toJSON()` instead | ||
* Returns an array representation of the array view. | ||
* | ||
* @returns {Array<number>} | ||
*/ | ||
toObject() { | ||
return this.toJSON(); | ||
} | ||
/** | ||
* @private | ||
* @type {string} | ||
* Returns an array representation of the array view. | ||
* | ||
* @returns {Array<number>} | ||
*/ | ||
TypedArrayView.typeGetter = typeGetters[type]; | ||
toJSON() { | ||
return [...this]; | ||
} | ||
/** | ||
* @private | ||
* @type {string} | ||
* Returns the byte length of an array view to hold a given amount of numbers. | ||
* | ||
* @param {number} size | ||
* @returns {number} | ||
*/ | ||
TypedArrayView.typeSetter = typeSetters[type]; | ||
static getLength(size) { | ||
return size << this.offset; | ||
} | ||
/** | ||
* @private | ||
* @type {number} | ||
* Creates an array view from a given array of numbers. | ||
* | ||
* @param {ArrayLike<number>} value | ||
* @param {TypedArrayView} [array] | ||
* @returns {TypedArrayView} | ||
*/ | ||
TypedArrayView.offset = typeOffsets[type]; | ||
static from(value, array) { | ||
const dataArray = array || this.of(value.length); | ||
const { size } = dataArray; | ||
for (let i = 0; i < size; i++) { | ||
dataArray.set(i, value[i]); | ||
} | ||
return dataArray; | ||
} | ||
/** | ||
* @private | ||
* @type {boolean} | ||
* Creates an empty array view of specified size. | ||
* | ||
* @param {number} size | ||
* @returns {TypedArrayView} | ||
*/ | ||
TypedArrayView.littleEndian = !!littleEndian; | ||
static of(size = 1) { | ||
const buffer = new ArrayBuffer(this.getLength(size)); | ||
return new this(buffer); | ||
} | ||
} | ||
return TypedArrayView; | ||
/** | ||
* @type {string} | ||
*/ | ||
TypedArrayView.typeGetter = ''; | ||
/** | ||
* @type {string} | ||
*/ | ||
TypedArrayView.typeSetter = ''; | ||
/** | ||
* @type {number} | ||
*/ | ||
TypedArrayView.offset = 0; | ||
/** | ||
* @type {boolean} | ||
*/ | ||
TypedArrayView.littleEndian = false; | ||
/** | ||
* @param {string} type | ||
* @param {boolean} [littleEndian] | ||
* @returns {Class<Base>} | ||
*/ | ||
function TypedArrayViewMixin(type, littleEndian) { | ||
class Base extends TypedArrayView {} | ||
Base.typeGetter = typeGetters[type]; | ||
Base.typeSetter = typeSetters[type]; | ||
Base.offset = typeOffsets[type]; | ||
Base.littleEndian = !!littleEndian; | ||
return Base; | ||
} | ||
module.exports = TypedArrayViewMixin; |
{ | ||
"name": "structurae", | ||
"version": "1.7.1", | ||
"version": "1.7.2", | ||
"description": "Data structures for performance-sensitive modern JavaScript applications.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -9,3 +9,3 @@ # Structurae | ||
- [Binary Structures](https://github.com/zandaqo/structurae#Binary_Structures): | ||
- [Binary Structures](https://github.com/zandaqo/structurae#binary-structures): | ||
- [ArrayView](https://github.com/zandaqo/structurae#ArrayView) - an array of C-like structs, ObjectViews, implemented with DataView | ||
@@ -12,0 +12,0 @@ - [ObjectView](https://github.com/zandaqo/structurae#ObjectView) - extends DataView to implement C-like struct. |
196573
5550