Skip to content

Instantly share code, notes, and snippets.

@sjkillen
Created July 21, 2017 06:05
Show Gist options
  • Save sjkillen/d6c1facdb3fd682a3ecb1f12adbe92e9 to your computer and use it in GitHub Desktop.
Save sjkillen/d6c1facdb3fd682a3ecb1f12adbe92e9 to your computer and use it in GitHub Desktop.
/**
* index.js
* July 20th 2017
*/
"use strict";
function DataViewObject() {
}
DataViewObject.Uint8 = Symbol("DataViewObject Type: Uint8");
DataViewObject.Uint16 = Symbol("DataViewObject Type: Uint16");
DataViewObject.Uint32 = Symbol("DataViewObject Type: Uint32");
DataViewObject.Int8 = Symbol("DataViewObject Type: Int8");
DataViewObject.Int16 = Symbol("DataViewObject Type: Int16");
DataViewObject.Int32 = Symbol("DataViewObject Type: Int32");
DataViewObject.Float32 = Symbol("DataViewObject Type: Float34");
DataViewObject.Float64 = Symbol("DataViewObject Type: Float64");
const write = {
[DataViewObject.Uint8]: DataView.prototype.setUint8,
[DataViewObject.Uint16]: DataView.prototype.setUint16,
[DataViewObject.Uint32]: DataView.prototype.setUint32,
[DataViewObject.Int8]: DataView.prototype.setInt8,
[DataViewObject.Int16]: DataView.prototype.setInt16,
[DataViewObject.Int32]: DataView.prototype.setInt32,
[DataViewObject.Float32]: DataView.prototype.setFloat32,
[DataViewObject.Float64]: DataView.prototype.setFloat64
};
const read = {
[DataViewObject.Uint8]: DataView.prototype.getUint8,
[DataViewObject.Uint16]: DataView.prototype.getUint16,
[DataViewObject.Uint32]: DataView.prototype.getUint32,
[DataViewObject.Int8]: DataView.prototype.getInt8,
[DataViewObject.Int16]: DataView.prototype.getInt16,
[DataViewObject.Int32]: DataView.prototype.getInt32,
[DataViewObject.Float32]: DataView.prototype.getFloat32,
[DataViewObject.Float64]: DataView.prototype.getFloat64
};
const sizes = {
[DataViewObject.Uint8]: 1,
[DataViewObject.Uint16]: 2,
[DataViewObject.Uint32]:4,
[DataViewObject.Int8]: 1,
[DataViewObject.Int16]: 2,
[DataViewObject.Int32]: 4,
[DataViewObject.Float32]: 4,
[DataViewObject.Float64]: 8
};
DataViewObject.prototype = new Proxy({}, {
get(target, prop, reciever) {
return Reflect.get(Object.prototype, prop, reciever);
},
set(target, prop, value, reciever) {
const forceType = typeof value === "symbol";
const type = forceType ? value : inferType(value);
const buffer = new ArrayBuffer(sizes[type]);
const view = new DataView(buffer, 0);
// Initialize value
if (!forceType) {
write[type].call(view, 0, value, true);
}
Object.defineProperty(reciever, prop, {
get() {
return read[type].call(view, 0, true);
},
set(v) {
write[type].call(view, 0, v, true);
}
});
console.log(`Initializing prop ${String(prop)} as type ${String(type)}`);
return true;
}
});
/**
* Return the appropriate type symbol for number
* @param {number} num
*/
function inferType(num) {
if (Math.trunc(num) === num) {
return DataViewObject.Int32;
} else {
return DataViewObject.Float64;
}
}
/**
* example.js
*/
class HumanRecord extends DataViewObject {
constructor(id) {
super();
this.age = 18; // Inferred to be an Int32
this.money = 3000.729 // Inferred to be a Float64
this.id = DataViewObject.Uint8; // Force type to be Uint32 (initialized to 0)
this.id = id;
this.id += 255; // Overflow type, making id - 1
this.age = 18.9800890 // Truncated to 18
}
info() {
console.log(`Human num ${this.id} is ${this.age} years old and has $${this.money}`)
}
}
const a = new HumanRecord(100);
a.info();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment