basant307/AI_Governance_Project
048
1"use strict";2module.exports = Writer;3 4var util = require("./util/minimal");5 6var BufferWriter; // cyclic7 8var LongBits = util.LongBits,9 base64 = util.base64,10 utf8 = util.utf8;11 12/**13 * Constructs a new writer operation instance.14 * @classdesc Scheduled writer operation.15 * @constructor16 * @param {function(*, Uint8Array, number)} fn Function to call17 * @param {number} len Value byte length18 * @param {*} val Value to write19 * @ignore20 */21function Op(fn, len, val) {22 23 /**24 * Function to call.25 * @type {function(Uint8Array, number, *)}26 */27 this.fn = fn;28 29 /**30 * Value byte length.31 * @type {number}32 */33 this.len = len;34 35 /**36 * Next operation.37 * @type {Writer.Op|undefined}38 */39 this.next = undefined;40 41 /**42 * Value to write.43 * @type {*}44 */45 this.val = val; // type varies46}47 48/* istanbul ignore next */49function noop() {} // eslint-disable-line no-empty-function50 51/**52 * Constructs a new writer state instance.53 * @classdesc Copied writer state.54 * @memberof Writer55 * @constructor56 * @param {Writer} writer Writer to copy state from57 * @ignore58 */59function State(writer) {60 61 /**62 * Current head.63 * @type {Writer.Op}64 */65 this.head = writer.head;66 67 /**68 * Current tail.69 * @type {Writer.Op}70 */71 this.tail = writer.tail;72 73 /**74 * Current buffer length.75 * @type {number}76 */77 this.len = writer.len;78 79 /**80 * Next state.81 * @type {State|null}82 */83 this.next = writer.states;84}85 86/**87 * Constructs a new writer instance.88 * @classdesc Wire format writer using `Uint8Array` if available, otherwise `Array`.89 * @constructor90 */91function Writer() {92 93 /**94 * Current length.95 * @type {number}96 */97 this.len = 0;98 99 /**100 * Operations head.101 * @type {Object}102 */103 this.head = new Op(noop, 0, 0);104 105 /**106 * Operations tail107 * @type {Object}108 */109 this.tail = this.head;110 111 /**112 * Linked forked states.113 * @type {Object|null}114 */115 this.states = null;116 117 // When a value is written, the writer calculates its byte length and puts it into a linked118 // list of operations to perform when finish() is called. This both allows us to allocate119 // buffers of the exact required size and reduces the amount of work we have to do compared120 // to first calculating over objects and then encoding over objects. In our case, the encoding121 // part is just a linked list walk calling operations with already prepared values.122}123 124var create = function create() {125 return util.Buffer126 ? function create_buffer_setup() {127 return (Writer.create = function create_buffer() {128 return new BufferWriter();129 })();130 }131 /* istanbul ignore next */132 : function create_array() {133 return new Writer();134 };135};136 137/**138 * Creates a new writer.139 * @function140 * @returns {BufferWriter|Writer} A {@link BufferWriter} when Buffers are supported, otherwise a {@link Writer}141 */142Writer.create = create();143 144/**145 * Allocates a buffer of the specified size.146 * @param {number} size Buffer size147 * @returns {Uint8Array} Buffer148 */149Writer.alloc = function alloc(size) {150 return new util.Array(size);151};152 153// Use Uint8Array buffer pool in the browser, just like node does with buffers154/* istanbul ignore else */155if (util.Array !== Array)156 Writer.alloc = util.pool(Writer.alloc, util.Array.prototype.subarray);157 158/**159 * Pushes a new operation to the queue.160 * @param {function(Uint8Array, number, *)} fn Function to call161 * @param {number} len Value byte length162 * @param {number} val Value to write163 * @returns {Writer} `this`164 * @private165 */166Writer.prototype._push = function push(fn, len, val) {167 this.tail = this.tail.next = new Op(fn, len, val);168 this.len += len;169 return this;170};171 172function writeByte(val, buf, pos) {173 buf[pos] = val & 255;174}175 176function writeVarint32(val, buf, pos) {177 while (val > 127) {178 buf[pos++] = val & 127 | 128;179 val >>>= 7;180 }181 buf[pos] = val;182}183 184/**185 * Constructs a new varint writer operation instance.186 * @classdesc Scheduled varint writer operation.187 * @extends Op188 * @constructor189 * @param {number} len Value byte length190 * @param {number} val Value to write191 * @ignore192 */193function VarintOp(len, val) {194 this.len = len;195 this.next = undefined;196 this.val = val;197}198 199VarintOp.prototype = Object.create(Op.prototype);200VarintOp.prototype.fn = writeVarint32;201 202/**203 * Writes an unsigned 32 bit value as a varint.204 * @param {number} value Value to write205 * @returns {Writer} `this`206 */207Writer.prototype.uint32 = function write_uint32(value) {208 // here, the call to this.push has been inlined and a varint specific Op subclass is used.209 // uint32 is by far the most frequently used operation and benefits significantly from this.210 this.len += (this.tail = this.tail.next = new VarintOp(211 (value = value >>> 0)212 < 128 ? 1213 : value < 16384 ? 2214 : value < 2097152 ? 3215 : value < 268435456 ? 4216 : 5,217 value)).len;218 return this;219};220 221/**222 * Writes a signed 32 bit value as a varint.223 * @function224 * @param {number} value Value to write225 * @returns {Writer} `this`226 */227Writer.prototype.int32 = function write_int32(value) {228 return (value |= 0) < 0229 ? this._push(writeVarint64, 10, LongBits.fromNumber(value)) // 10 bytes per spec230 : this.uint32(value);231};232 233/**234 * Writes a 32 bit value as a varint, zig-zag encoded.235 * @param {number} value Value to write236 * @returns {Writer} `this`237 */238Writer.prototype.sint32 = function write_sint32(value) {239 return this.uint32((value << 1 ^ value >> 31) >>> 0);240};241 242function writeVarint64(val, buf, pos) {243 var lo = val.lo,244 hi = val.hi;245 while (hi) {246 buf[pos++] = lo & 127 | 128;247 lo = (lo >>> 7 | hi << 25) >>> 0;248 hi >>>= 7;249 }250 while (lo > 127) {251 buf[pos++] = lo & 127 | 128;252 lo = lo >>> 7;253 }254 buf[pos++] = lo;255}256 257/**258 * Writes an unsigned 64 bit value as a varint.259 * @param {Long|number|string} value Value to write260 * @returns {Writer} `this`261 * @throws {TypeError} If `value` is a string and no long library is present.262 */263Writer.prototype.uint64 = function write_uint64(value) {264 var bits = LongBits.from(value);265 return this._push(writeVarint64, bits.length(), bits);266};267 268/**269 * Writes a signed 64 bit value as a varint.270 * @function271 * @param {Long|number|string} value Value to write272 * @returns {Writer} `this`273 * @throws {TypeError} If `value` is a string and no long library is present.274 */275Writer.prototype.int64 = Writer.prototype.uint64;276 277/**278 * Writes a signed 64 bit value as a varint, zig-zag encoded.279 * @param {Long|number|string} value Value to write280 * @returns {Writer} `this`281 * @throws {TypeError} If `value` is a string and no long library is present.282 */283Writer.prototype.sint64 = function write_sint64(value) {284 var bits = LongBits.from(value).zzEncode();285 return this._push(writeVarint64, bits.length(), bits);286};287 288/**289 * Writes a boolish value as a varint.290 * @param {boolean} value Value to write291 * @returns {Writer} `this`292 */293Writer.prototype.bool = function write_bool(value) {294 return this._push(writeByte, 1, value ? 1 : 0);295};296 297function writeFixed32(val, buf, pos) {298 buf[pos ] = val & 255;299 buf[pos + 1] = val >>> 8 & 255;300 buf[pos + 2] = val >>> 16 & 255;301 buf[pos + 3] = val >>> 24;302}303 304/**305 * Writes an unsigned 32 bit value as fixed 32 bits.306 * @param {number} value Value to write307 * @returns {Writer} `this`308 */309Writer.prototype.fixed32 = function write_fixed32(value) {310 return this._push(writeFixed32, 4, value >>> 0);311};312 313/**314 * Writes a signed 32 bit value as fixed 32 bits.315 * @function316 * @param {number} value Value to write317 * @returns {Writer} `this`318 */319Writer.prototype.sfixed32 = Writer.prototype.fixed32;320 321/**322 * Writes an unsigned 64 bit value as fixed 64 bits.323 * @param {Long|number|string} value Value to write324 * @returns {Writer} `this`325 * @throws {TypeError} If `value` is a string and no long library is present.326 */327Writer.prototype.fixed64 = function write_fixed64(value) {328 var bits = LongBits.from(value);329 return this._push(writeFixed32, 4, bits.lo)._push(writeFixed32, 4, bits.hi);330};331 332/**333 * Writes a signed 64 bit value as fixed 64 bits.334 * @function335 * @param {Long|number|string} value Value to write336 * @returns {Writer} `this`337 * @throws {TypeError} If `value` is a string and no long library is present.338 */339Writer.prototype.sfixed64 = Writer.prototype.fixed64;340 341/**342 * Writes a float (32 bit).343 * @function344 * @param {number} value Value to write345 * @returns {Writer} `this`346 */347Writer.prototype.float = function write_float(value) {348 return this._push(util.float.writeFloatLE, 4, value);349};350 351/**352 * Writes a double (64 bit float).353 * @function354 * @param {number} value Value to write355 * @returns {Writer} `this`356 */357Writer.prototype.double = function write_double(value) {358 return this._push(util.float.writeDoubleLE, 8, value);359};360 361var writeBytes = util.Array.prototype.set362 ? function writeBytes_set(val, buf, pos) {363 buf.set(val, pos); // also works for plain array values364 }365 /* istanbul ignore next */366 : function writeBytes_for(val, buf, pos) {367 for (var i = 0; i < val.length; ++i)368 buf[pos + i] = val[i];369 };370 371/**372 * Writes a sequence of bytes.373 * @param {Uint8Array|string} value Buffer or base64 encoded string to write374 * @returns {Writer} `this`375 */376Writer.prototype.bytes = function write_bytes(value) {377 var len = value.length >>> 0;378 if (!len)379 return this._push(writeByte, 1, 0);380 if (util.isString(value)) {381 var buf = Writer.alloc(len = base64.length(value));382 base64.decode(value, buf, 0);383 value = buf;384 }385 return this.uint32(len)._push(writeBytes, len, value);386};387 388/**389 * Writes a string.390 * @param {string} value Value to write391 * @returns {Writer} `this`392 */393Writer.prototype.string = function write_string(value) {394 var len = utf8.length(value);395 return len396 ? this.uint32(len)._push(utf8.write, len, value)397 : this._push(writeByte, 1, 0);398};399 400/**401 * Forks this writer's state by pushing it to a stack.402 * Calling {@link Writer#reset|reset} or {@link Writer#ldelim|ldelim} resets the writer to the previous state.403 * @returns {Writer} `this`404 */405Writer.prototype.fork = function fork() {406 this.states = new State(this);407 this.head = this.tail = new Op(noop, 0, 0);408 this.len = 0;409 return this;410};411 412/**413 * Resets this instance to the last state.414 * @returns {Writer} `this`415 */416Writer.prototype.reset = function reset() {417 if (this.states) {418 this.head = this.states.head;419 this.tail = this.states.tail;420 this.len = this.states.len;421 this.states = this.states.next;422 } else {423 this.head = this.tail = new Op(noop, 0, 0);424 this.len = 0;425 }426 return this;427};428 429/**430 * Resets to the last state and appends the fork state's current write length as a varint followed by its operations.431 * @returns {Writer} `this`432 */433Writer.prototype.ldelim = function ldelim() {434 var head = this.head,435 tail = this.tail,436 len = this.len;437 this.reset().uint32(len);438 if (len) {439 this.tail.next = head.next; // skip noop440 this.tail = tail;441 this.len += len;442 }443 return this;444};445 446/**447 * Finishes the write operation.448 * @returns {Uint8Array} Finished buffer449 */450Writer.prototype.finish = function finish() {451 var head = this.head.next, // skip noop452 buf = this.constructor.alloc(this.len),453 pos = 0;454 while (head) {455 head.fn(head.val, buf, pos);456 pos += head.len;457 head = head.next;458 }459 // this.head = this.tail = null;460 return buf;461};462 463Writer._configure = function(BufferWriter_) {464 BufferWriter = BufferWriter_;465 Writer.create = create();466 BufferWriter._configure();467};468 