summaryrefslogtreecommitdiff
path: root/node_modules/capnp-ts/src/serialization/segment.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/capnp-ts/src/serialization/segment.js')
-rw-r--r--node_modules/capnp-ts/src/serialization/segment.js370
1 files changed, 370 insertions, 0 deletions
diff --git a/node_modules/capnp-ts/src/serialization/segment.js b/node_modules/capnp-ts/src/serialization/segment.js
new file mode 100644
index 0000000..984a065
--- /dev/null
+++ b/node_modules/capnp-ts/src/serialization/segment.js
@@ -0,0 +1,370 @@
+"use strict";
+/**
+ * @author jdiaz5513
+ */
+var _a;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Segment = void 0;
+const tslib_1 = require("tslib");
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const constants_1 = require("../constants");
+const errors_1 = require("../errors");
+const types_1 = require("../types");
+const util_1 = require("../util");
+const pointers_1 = require("./pointers");
+const trace = debug_1.default("capnp:segment");
+trace("load");
+class Segment {
+ constructor(id, message, buffer, byteLength = 0) {
+ this[_a] = "Segment";
+ this.id = id;
+ this.message = message;
+ this.buffer = buffer;
+ this._dv = new DataView(buffer);
+ this.byteOffset = 0;
+ this.byteLength = byteLength;
+ }
+ /**
+ * Attempt to allocate the requested number of bytes in this segment. If this segment is full this method will return
+ * a pointer to freshly allocated space in another segment from the same message.
+ *
+ * @param {number} byteLength The number of bytes to allocate, will be rounded up to the nearest word.
+ * @returns {Pointer} A pointer to the newly allocated space.
+ */
+ allocate(byteLength) {
+ trace("allocate(%d)", byteLength);
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
+ let segment = this;
+ byteLength = util_1.padToWord(byteLength);
+ if (byteLength > constants_1.MAX_SEGMENT_LENGTH - 8) {
+ throw new Error(util_1.format(errors_1.SEG_SIZE_OVERFLOW, byteLength));
+ }
+ if (!segment.hasCapacity(byteLength)) {
+ segment = segment.message.allocateSegment(byteLength);
+ }
+ const byteOffset = segment.byteLength;
+ segment.byteLength = segment.byteLength + byteLength;
+ trace("Allocated %x bytes in %s (requested segment: %s).", byteLength, this, segment);
+ return new pointers_1.Pointer(segment, byteOffset);
+ }
+ /**
+ * Quickly copy a word (8 bytes) from `srcSegment` into this one at the given offset.
+ *
+ * @param {number} byteOffset The offset to write the word to.
+ * @param {Segment} srcSegment The segment to copy the word from.
+ * @param {number} srcByteOffset The offset from the start of `srcSegment` to copy from.
+ * @returns {void}
+ */
+ copyWord(byteOffset, srcSegment, srcByteOffset) {
+ const value = srcSegment._dv.getFloat64(srcByteOffset, constants_1.NATIVE_LITTLE_ENDIAN);
+ this._dv.setFloat64(byteOffset, value, constants_1.NATIVE_LITTLE_ENDIAN);
+ }
+ /**
+ * Quickly copy words from `srcSegment` into this one.
+ *
+ * @param {number} byteOffset The offset to start copying into.
+ * @param {Segment} srcSegment The segment to copy from.
+ * @param {number} srcByteOffset The start offset to copy from.
+ * @param {number} wordLength The number of words to copy.
+ * @returns {void}
+ */
+ copyWords(byteOffset, srcSegment, srcByteOffset, wordLength) {
+ const dst = new Float64Array(this.buffer, byteOffset, wordLength);
+ const src = new Float64Array(srcSegment.buffer, srcByteOffset, wordLength);
+ dst.set(src);
+ }
+ /**
+ * Quickly fill a number of words in the buffer with zeroes.
+ *
+ * @param {number} byteOffset The first byte to set to zero.
+ * @param {number} wordLength The number of words (not bytes!) to zero out.
+ * @returns {void}
+ */
+ fillZeroWords(byteOffset, wordLength) {
+ new Float64Array(this.buffer, byteOffset, wordLength).fill(0);
+ }
+ /** WARNING: This function is not yet implemented. */
+ getBigInt64(byteOffset, littleEndian) {
+ throw new Error(util_1.format(errors_1.NOT_IMPLEMENTED, byteOffset, littleEndian));
+ }
+ /** WARNING: This function is not yet implemented. */
+ getBigUint64(byteOffset, littleEndian) {
+ throw new Error(util_1.format(errors_1.NOT_IMPLEMENTED, byteOffset, littleEndian));
+ }
+ /**
+ * Get the total number of bytes available in this segment (the size of its underlying buffer).
+ *
+ * @returns {number} The total number of bytes this segment can hold.
+ */
+ getCapacity() {
+ return this.buffer.byteLength;
+ }
+ /**
+ * Read a float32 value out of this segment.
+ *
+ * @param {number} byteOffset The offset in bytes to the value.
+ * @returns {number} The value.
+ */
+ getFloat32(byteOffset) {
+ return this._dv.getFloat32(byteOffset, true);
+ }
+ /**
+ * Read a float64 value out of this segment.
+ *
+ * @param {number} byteOffset The offset in bytes to the value.
+ * @returns {number} The value.
+ */
+ getFloat64(byteOffset) {
+ return this._dv.getFloat64(byteOffset, true);
+ }
+ /**
+ * Read an int16 value out of this segment.
+ *
+ * @param {number} byteOffset The offset in bytes to the value.
+ * @returns {number} The value.
+ */
+ getInt16(byteOffset) {
+ return this._dv.getInt16(byteOffset, true);
+ }
+ /**
+ * Read an int32 value out of this segment.
+ *
+ * @param {number} byteOffset The offset in bytes to the value.
+ * @returns {number} The value.
+ */
+ getInt32(byteOffset) {
+ return this._dv.getInt32(byteOffset, true);
+ }
+ /**
+ * Read an int64 value out of this segment.
+ *
+ * @param {number} byteOffset The offset in bytes to the value.
+ * @returns {number} The value.
+ */
+ getInt64(byteOffset) {
+ return new types_1.Int64(new Uint8Array(this.buffer.slice(byteOffset, byteOffset + 8)));
+ }
+ /**
+ * Read an int8 value out of this segment.
+ *
+ * @param {number} byteOffset The offset in bytes to the value.
+ * @returns {number} The value.
+ */
+ getInt8(byteOffset) {
+ return this._dv.getInt8(byteOffset);
+ }
+ /**
+ * Read a uint16 value out of this segment.
+ *
+ * @param {number} byteOffset The offset in bytes to the value.
+ * @returns {number} The value.
+ */
+ getUint16(byteOffset) {
+ return this._dv.getUint16(byteOffset, true);
+ }
+ /**
+ * Read a uint32 value out of this segment.
+ *
+ * @param {number} byteOffset The offset in bytes to the value.
+ * @returns {number} The value.
+ */
+ getUint32(byteOffset) {
+ return this._dv.getUint32(byteOffset, true);
+ }
+ /**
+ * Read a uint8 value out of this segment.
+ * NOTE: this does not copy the memory region, so updates to the underlying buffer will affect the Uint64 value!
+ *
+ * @param {number} byteOffset The offset in bytes to the value.
+ * @returns {number} The value.
+ */
+ getUint64(byteOffset) {
+ return new types_1.Uint64(new Uint8Array(this.buffer.slice(byteOffset, byteOffset + 8)));
+ }
+ /**
+ * Read a uint8 value out of this segment.
+ *
+ * @param {number} byteOffset The offset in bytes to the value.
+ * @returns {number} The value.
+ */
+ getUint8(byteOffset) {
+ return this._dv.getUint8(byteOffset);
+ }
+ hasCapacity(byteLength) {
+ trace("hasCapacity(%d)", byteLength);
+ // capacity - allocated >= requested
+ return this.buffer.byteLength - this.byteLength >= byteLength;
+ }
+ /**
+ * Quickly check the word at the given offset to see if it is equal to zero.
+ *
+ * PERF_V8: Fastest way to do this is by reading the whole word as a `number` (float64) in the _native_ endian format
+ * and see if it's zero.
+ *
+ * Benchmark: http://jsben.ch/#/Pjooc
+ *
+ * @param {number} byteOffset The offset to the word.
+ * @returns {boolean} `true` if the word is zero.
+ */
+ isWordZero(byteOffset) {
+ return this._dv.getFloat64(byteOffset, constants_1.NATIVE_LITTLE_ENDIAN) === 0;
+ }
+ /**
+ * Swap out this segment's underlying buffer with a new one. It's assumed that the new buffer has the same content but
+ * more free space, otherwise all existing pointers to this segment will be hilariously broken.
+ *
+ * @param {ArrayBuffer} buffer The new buffer to use.
+ * @returns {void}
+ */
+ replaceBuffer(buffer) {
+ trace("replaceBuffer(%p)", buffer);
+ if (this.buffer === buffer)
+ return;
+ if (buffer.byteLength < this.byteLength) {
+ throw new Error(errors_1.SEG_REPLACEMENT_BUFFER_TOO_SMALL);
+ }
+ this._dv = new DataView(buffer);
+ this.buffer = buffer;
+ }
+ /** WARNING: This function is not yet implemented. */
+ setBigInt64(byteOffset, value, littleEndian) {
+ throw new Error(util_1.format(errors_1.NOT_IMPLEMENTED, byteOffset, value, littleEndian));
+ }
+ /** WARNING: This function is not yet implemented. */
+ setBigUint64(byteOffset, value, littleEndian) {
+ throw new Error(util_1.format(errors_1.NOT_IMPLEMENTED, byteOffset, value, littleEndian));
+ }
+ /**
+ * Write a float32 value to the specified offset.
+ *
+ * @param {number} byteOffset The offset from the beginning of the buffer.
+ * @param {number} val The value to store.
+ * @returns {void}
+ */
+ setFloat32(byteOffset, val) {
+ this._dv.setFloat32(byteOffset, val, true);
+ }
+ /**
+ * Write an float64 value to the specified offset.
+ *
+ * @param {number} byteOffset The offset from the beginning of the buffer.
+ * @param {number} val The value to store.
+ * @returns {void}
+ */
+ setFloat64(byteOffset, val) {
+ this._dv.setFloat64(byteOffset, val, true);
+ }
+ /**
+ * Write an int16 value to the specified offset.
+ *
+ * @param {number} byteOffset The offset from the beginning of the buffer.
+ * @param {number} val The value to store.
+ * @returns {void}
+ */
+ setInt16(byteOffset, val) {
+ this._dv.setInt16(byteOffset, val, true);
+ }
+ /**
+ * Write an int32 value to the specified offset.
+ *
+ * @param {number} byteOffset The offset from the beginning of the buffer.
+ * @param {number} val The value to store.
+ * @returns {void}
+ */
+ setInt32(byteOffset, val) {
+ this._dv.setInt32(byteOffset, val, true);
+ }
+ /**
+ * Write an int8 value to the specified offset.
+ *
+ * @param {number} byteOffset The offset from the beginning of the buffer.
+ * @param {number} val The value to store.
+ * @returns {void}
+ */
+ setInt8(byteOffset, val) {
+ this._dv.setInt8(byteOffset, val);
+ }
+ /**
+ * Write an int64 value to the specified offset.
+ *
+ * @param {number} byteOffset The offset from the beginning of the buffer.
+ * @param {Int64} val The value to store.
+ * @returns {void}
+ */
+ setInt64(byteOffset, val) {
+ this._dv.setUint8(byteOffset, val.buffer[0]);
+ this._dv.setUint8(byteOffset + 1, val.buffer[1]);
+ this._dv.setUint8(byteOffset + 2, val.buffer[2]);
+ this._dv.setUint8(byteOffset + 3, val.buffer[3]);
+ this._dv.setUint8(byteOffset + 4, val.buffer[4]);
+ this._dv.setUint8(byteOffset + 5, val.buffer[5]);
+ this._dv.setUint8(byteOffset + 6, val.buffer[6]);
+ this._dv.setUint8(byteOffset + 7, val.buffer[7]);
+ }
+ /**
+ * Write a uint16 value to the specified offset.
+ *
+ * @param {number} byteOffset The offset from the beginning of the buffer.
+ * @param {number} val The value to store.
+ * @returns {void}
+ */
+ setUint16(byteOffset, val) {
+ this._dv.setUint16(byteOffset, val, true);
+ }
+ /**
+ * Write a uint32 value to the specified offset.
+ *
+ * @param {number} byteOffset The offset from the beginning of the buffer.
+ * @param {number} val The value to store.
+ * @returns {void}
+ */
+ setUint32(byteOffset, val) {
+ this._dv.setUint32(byteOffset, val, true);
+ }
+ /**
+ * Write a uint64 value to the specified offset.
+ * TODO: benchmark other ways to perform this write operation.
+ *
+ * @param {number} byteOffset The offset from the beginning of the buffer.
+ * @param {Uint64} val The value to store.
+ * @returns {void}
+ */
+ setUint64(byteOffset, val) {
+ this._dv.setUint8(byteOffset + 0, val.buffer[0]);
+ this._dv.setUint8(byteOffset + 1, val.buffer[1]);
+ this._dv.setUint8(byteOffset + 2, val.buffer[2]);
+ this._dv.setUint8(byteOffset + 3, val.buffer[3]);
+ this._dv.setUint8(byteOffset + 4, val.buffer[4]);
+ this._dv.setUint8(byteOffset + 5, val.buffer[5]);
+ this._dv.setUint8(byteOffset + 6, val.buffer[6]);
+ this._dv.setUint8(byteOffset + 7, val.buffer[7]);
+ }
+ /**
+ * Write a uint8 (byte) value to the specified offset.
+ *
+ * @param {number} byteOffset The offset from the beginning of the buffer.
+ * @param {number} val The value to store.
+ * @returns {void}
+ */
+ setUint8(byteOffset, val) {
+ this._dv.setUint8(byteOffset, val);
+ }
+ /**
+ * Write a zero word (8 bytes) to the specified offset. This is slightly faster than calling `setUint64` or
+ * `setFloat64` with a zero value.
+ *
+ * Benchmark: http://jsben.ch/#/dUdPI
+ *
+ * @param {number} byteOffset The offset of the word to set to zero.
+ * @returns {void}
+ */
+ setWordZero(byteOffset) {
+ this._dv.setFloat64(byteOffset, 0, constants_1.NATIVE_LITTLE_ENDIAN);
+ }
+ toString() {
+ return util_1.format("Segment_id:%d,off:%a,len:%a,cap:%a", this.id, this.byteLength, this.byteOffset, this.buffer.byteLength);
+ }
+}
+exports.Segment = Segment;
+_a = Symbol.toStringTag;
+//# sourceMappingURL=segment.js.map \ No newline at end of file