UNPKG

bytebuffer

Version:

The swiss army knife for binary data in JavaScript.

197 lines (188 loc) 6.56 kB
//? if (UTF8STRING && UTF8) { // types/strings/utf8string /** * Metrics representing number of UTF8 characters. Evaluates to `c`. * @type {string} * @const * @expose */ ByteBuffer.METRICS_CHARS = 'c'; /** * Metrics representing number of bytes. Evaluates to `b`. * @type {string} * @const * @expose */ ByteBuffer.METRICS_BYTES = 'b'; /** * Writes an UTF8 encoded string. * @param {string} str String to write * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted. * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written. * @expose */ ByteBufferPrototype.writeUTF8String = function(str, offset) { //? RELATIVE(); if (!this.noAssert) { //? ASSERT_OFFSET(); } var k; //? if (NODE) { k = Buffer.byteLength(str, "utf8"); //? ENSURE_CAPACITY('k'); offset += this.buffer.write(str, offset, k, "utf8"); if (relative) { this.offset = offset; return this; } return k; //? } else { var start = offset; k = utfx.calculateUTF16asUTF8(stringSource(str))[1]; //? ENSURE_CAPACITY('k'); utfx.encodeUTF16toUTF8(stringSource(str), function(b) { this.view.setUint8(offset++, b); }.bind(this)); if (relative) { this.offset = offset; return this; } return offset - start; //? } }; //? if (ALIASES) { /** * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}. * @function * @param {string} str String to write * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted. * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written. * @expose */ ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String; //? } /** * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's * `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF. * @function * @param {string} str String to calculate * @returns {number} Number of UTF8 characters * @expose */ ByteBuffer.calculateUTF8Chars = function(str) { return utfx.calculateUTF16asUTF8(stringSource(str))[0]; }; /** * Calculates the number of UTF8 bytes of a string. * @function * @param {string} str String to calculate * @returns {number} Number of UTF8 bytes * @expose */ ByteBuffer.calculateUTF8Bytes = function(str) { //? if (NODE) { if (typeof str !== 'string') throw TypeError("Illegal argument: "+(typeof str)); return Buffer.byteLength(str, "utf8"); //? } else return utfx.calculateUTF16asUTF8(stringSource(str))[1]; }; /** * Reads an UTF8 encoded string. * @param {number} length Number of characters or bytes to read. * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to * {@link ByteBuffer.METRICS_CHARS}. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes * read if omitted. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string * read and the actual number of bytes read. * @expose */ ByteBufferPrototype.readUTF8String = function(length, metrics, offset) { if (typeof metrics === 'number') { offset = metrics; metrics = undefined; } //? RELATIVE(); if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS; if (!this.noAssert) { //? ASSERT_INTEGER('length'); //? ASSERT_OFFSET(); } var i = 0, start = offset, //? if (NODE) temp, sd; if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser sd = stringDestination(); utfx.decodeUTF8(function() { //? if (NODE) return i < length && offset < this.limit ? this.buffer[offset++] : null; //? else return i < length && offset < this.limit ? this.view.getUint8(offset++) : null; }.bind(this), function(cp) { ++i; utfx.UTF8toUTF16(cp, sd); }.bind(this)); if (i !== length) throw RangeError("Illegal range: Truncated data, "+i+" == "+length); if (relative) { this.offset = offset; return sd(); } else { return { "string": sd(), "length": offset - start }; } } else if (metrics === ByteBuffer.METRICS_BYTES) { if (!this.noAssert) { //? ASSERT_OFFSET('length'); } //? if (NODE) { temp = this.buffer.toString("utf8", offset, offset+length); if (relative) { this.offset += length; return temp; } else { return { 'string': temp, 'length': length }; } //? } else { var k = offset + length; utfx.decodeUTF8toUTF16(function() { return offset < k ? this.view.getUint8(offset++) : null; }.bind(this), sd = stringDestination(), this.noAssert); if (offset !== k) throw RangeError("Illegal range: Truncated data, "+offset+" == "+k); if (relative) { this.offset = offset; return sd(); } else { return { 'string': sd(), 'length': offset - start }; } //? } } else throw TypeError("Unsupported metrics: "+metrics); }; //? if (ALIASES) { /** * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}. * @function * @param {number} length Number of characters or bytes to read * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to * {@link ByteBuffer.METRICS_CHARS}. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes * read if omitted. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string * read and the actual number of bytes read. * @expose */ ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String; //? } //? }