| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 | 
							- /**
 
-  * @fileoverview A buffer implementation that can decode data for protobufs.
 
-  */
 
- goog.module('protobuf.binary.BufferDecoder');
 
- const ByteString = goog.require('protobuf.ByteString');
 
- const functions = goog.require('goog.functions');
 
- const {POLYFILL_TEXT_ENCODING, checkCriticalPositionIndex, checkCriticalState, checkState} = goog.require('protobuf.internal.checks');
 
- const {byteStringFromUint8ArrayUnsafe} = goog.require('protobuf.byteStringInternal');
 
- const {concatenateByteArrays} = goog.require('protobuf.binary.uint8arrays');
 
- const {decode} = goog.require('protobuf.binary.textencoding');
 
- /**
 
-  * Returns a valid utf-8 decoder function based on TextDecoder if available or
 
-  * a polyfill.
 
-  * Some of the environments we run in do not have TextDecoder defined.
 
-  * TextDecoder is faster than our polyfill so we prefer it over the polyfill.
 
-  * @return {function(!DataView): string}
 
-  */
 
- function getStringDecoderFunction() {
 
-   if (goog.global['TextDecoder']) {
 
-     const textDecoder = new goog.global['TextDecoder']('utf-8', {fatal: true});
 
-     return bytes => textDecoder.decode(bytes);
 
-   }
 
-   if (POLYFILL_TEXT_ENCODING) {
 
-     return decode;
 
-   } else {
 
-     throw new Error(
 
-         'TextDecoder is missing. ' +
 
-         'Enable protobuf.defines.POLYFILL_TEXT_ENCODING.');
 
-   }
 
- }
 
- /** @type {function(): function(!DataView): string} */
 
- const stringDecoderFunction =
 
-     functions.cacheReturnValue(() => getStringDecoderFunction());
 
- /** @type {function(): !DataView} */
 
- const emptyDataView =
 
-     functions.cacheReturnValue(() => new DataView(new ArrayBuffer(0)));
 
- class BufferDecoder {
 
-   /**
 
-    * @param {!Array<!BufferDecoder>} bufferDecoders
 
-    * @return {!BufferDecoder}
 
-    */
 
-   static merge(bufferDecoders) {
 
-     const uint8Arrays = bufferDecoders.map(b => b.asUint8Array());
 
-     const bytesArray = concatenateByteArrays(uint8Arrays);
 
-     return BufferDecoder.fromArrayBuffer(bytesArray.buffer);
 
-   }
 
-   /**
 
-    * @param {!ArrayBuffer} arrayBuffer
 
-    * @return {!BufferDecoder}
 
-    */
 
-   static fromArrayBuffer(arrayBuffer) {
 
-     return new BufferDecoder(
 
-         new DataView(arrayBuffer), 0, arrayBuffer.byteLength);
 
-   }
 
-   /**
 
-    * @param {!DataView} dataView
 
-    * @param {number} startIndex
 
-    * @param {number} length
 
-    * @private
 
-    */
 
-   constructor(dataView, startIndex, length) {
 
-     /** @private @const {!DataView} */
 
-     this.dataView_ = dataView;
 
-     /** @private @const {number} */
 
-     this.startIndex_ = startIndex;
 
-     /** @private @const {number} */
 
-     this.endIndex_ = startIndex + length;
 
-     /** @private {number} */
 
-     this.cursor_ = startIndex;
 
-   }
 
-   /**
 
-    * Returns the start index of the underlying buffer.
 
-    * @return {number}
 
-    */
 
-   startIndex() {
 
-     return this.startIndex_;
 
-   }
 
-   /**
 
-    * Returns the end index of the underlying buffer.
 
-    * @return {number}
 
-    */
 
-   endIndex() {
 
-     return this.endIndex_;
 
-   }
 
-   /**
 
-    * Returns the length of the underlying buffer.
 
-    * @return {number}
 
-    */
 
-   length() {
 
-     return this.endIndex_ - this.startIndex_;
 
-   }
 
-   /**
 
-    * Returns the start position of the next data, i.e. end position of the last
 
-    * read data + 1.
 
-    * @return {number}
 
-    */
 
-   cursor() {
 
-     return this.cursor_;
 
-   }
 
-   /**
 
-    * Sets the cursor to the specified position.
 
-    * @param {number} position
 
-    */
 
-   setCursor(position) {
 
-     this.cursor_ = position;
 
-   }
 
-   /**
 
-    * Returns if there is more data to read after the current cursor position.
 
-    * @return {boolean}
 
-    */
 
-   hasNext() {
 
-     return this.cursor_ < this.endIndex_;
 
-   }
 
-   /**
 
-    * Returns a float32 from a given index
 
-    * @param {number} index
 
-    * @return {number}
 
-    */
 
-   getFloat32(index) {
 
-     this.cursor_ = index + 4;
 
-     return this.dataView_.getFloat32(index, true);
 
-   }
 
-   /**
 
-    * Returns a float64 from a given index
 
-    * @param {number} index
 
-    * @return {number}
 
-    */
 
-   getFloat64(index) {
 
-     this.cursor_ = index + 8;
 
-     return this.dataView_.getFloat64(index, true);
 
-   }
 
-   /**
 
-    * Returns an int32 from a given index
 
-    * @param {number} index
 
-    * @return {number}
 
-    */
 
-   getInt32(index) {
 
-     this.cursor_ = index + 4;
 
-     return this.dataView_.getInt32(index, true);
 
-   }
 
-   /**
 
-    * Returns a uint32 from a given index
 
-    * @param {number} index
 
-    * @return {number}
 
-    */
 
-   getUint32(index) {
 
-     this.cursor_ = index + 4;
 
-     return this.dataView_.getUint32(index, true);
 
-   }
 
-   /**
 
-    * Returns two JS numbers each representing 32 bits of a 64 bit number. Also
 
-    * sets the cursor to the start of the next block of data.
 
-    * @param {number} index
 
-    * @return {{lowBits: number, highBits: number}}
 
-    */
 
-   getVarint(index) {
 
-     this.cursor_ = index;
 
-     let lowBits = 0;
 
-     let highBits = 0;
 
-     for (let shift = 0; shift < 28; shift += 7) {
 
-       const b = this.dataView_.getUint8(this.cursor_++);
 
-       lowBits |= (b & 0x7F) << shift;
 
-       if ((b & 0x80) === 0) {
 
-         return {lowBits, highBits};
 
-       }
 
-     }
 
-     const middleByte = this.dataView_.getUint8(this.cursor_++);
 
-     // last four bits of the first 32 bit number
 
-     lowBits |= (middleByte & 0x0F) << 28;
 
-     // 3 upper bits are part of the next 32 bit number
 
-     highBits = (middleByte & 0x70) >> 4;
 
-     if ((middleByte & 0x80) === 0) {
 
-       return {lowBits, highBits};
 
-     }
 
-     for (let shift = 3; shift <= 31; shift += 7) {
 
-       const b = this.dataView_.getUint8(this.cursor_++);
 
-       highBits |= (b & 0x7F) << shift;
 
-       if ((b & 0x80) === 0) {
 
-         return {lowBits, highBits};
 
-       }
 
-     }
 
-     checkCriticalState(false, 'Data is longer than 10 bytes');
 
-     return {lowBits, highBits};
 
-   }
 
-   /**
 
-    * Returns an unsigned int32 number at the current cursor position. The upper
 
-    * bits are discarded if the varint is longer than 32 bits. Also sets the
 
-    * cursor to the start of the next block of data.
 
-    * @return {number}
 
-    */
 
-   getUnsignedVarint32() {
 
-     let b = this.dataView_.getUint8(this.cursor_++);
 
-     let result = b & 0x7F;
 
-     if ((b & 0x80) === 0) {
 
-       return result;
 
-     }
 
-     b = this.dataView_.getUint8(this.cursor_++);
 
-     result |= (b & 0x7F) << 7;
 
-     if ((b & 0x80) === 0) {
 
-       return result;
 
-     }
 
-     b = this.dataView_.getUint8(this.cursor_++);
 
-     result |= (b & 0x7F) << 14;
 
-     if ((b & 0x80) === 0) {
 
-       return result;
 
-     }
 
-     b = this.dataView_.getUint8(this.cursor_++);
 
-     result |= (b & 0x7F) << 21;
 
-     if ((b & 0x80) === 0) {
 
-       return result;
 
-     }
 
-     // Extract only last 4 bits
 
-     b = this.dataView_.getUint8(this.cursor_++);
 
-     result |= (b & 0x0F) << 28;
 
-     for (let readBytes = 5; ((b & 0x80) !== 0) && readBytes < 10; readBytes++) {
 
-       b = this.dataView_.getUint8(this.cursor_++);
 
-     }
 
-     checkCriticalState((b & 0x80) === 0, 'Data is longer than 10 bytes');
 
-     // Result can be have 32 bits, convert it to unsigned
 
-     return result >>> 0;
 
-   }
 
-   /**
 
-    * Returns an unsigned int32 number at the specified index. The upper bits are
 
-    * discarded if the varint is longer than 32 bits. Also sets the cursor to the
 
-    * start of the next block of data.
 
-    * @param {number} index
 
-    * @return {number}
 
-    */
 
-   getUnsignedVarint32At(index) {
 
-     this.cursor_ = index;
 
-     return this.getUnsignedVarint32();
 
-   }
 
-   /**
 
-    * Seeks forward by the given amount.
 
-    * @param {number} skipAmount
 
-    * @package
 
-    */
 
-   skip(skipAmount) {
 
-     this.cursor_ += skipAmount;
 
-     checkCriticalPositionIndex(this.cursor_, this.endIndex_);
 
-   }
 
-   /**
 
-    * Skips over a varint from the current cursor position.
 
-    * @package
 
-    */
 
-   skipVarint() {
 
-     const startIndex = this.cursor_;
 
-     while (this.dataView_.getUint8(this.cursor_++) & 0x80) {
 
-     }
 
-     checkCriticalPositionIndex(this.cursor_, startIndex + 10);
 
-   }
 
-   /**
 
-    * @param {number} startIndex
 
-    * @param {number} length
 
-    * @return {!BufferDecoder}
 
-    */
 
-   subBufferDecoder(startIndex, length) {
 
-     checkState(
 
-         startIndex >= this.startIndex(),
 
-         `Current start: ${this.startIndex()}, subBufferDecoder start: ${
 
-             startIndex}`);
 
-     checkState(length >= 0, `Length: ${length}`);
 
-     checkState(
 
-         startIndex + length <= this.endIndex(),
 
-         `Current end: ${this.endIndex()}, subBufferDecoder start: ${
 
-             startIndex}, subBufferDecoder length: ${length}`);
 
-     return new BufferDecoder(this.dataView_, startIndex, length);
 
-   }
 
-   /**
 
-    * Returns the buffer as a string.
 
-    * @return {string}
 
-    */
 
-   asString() {
 
-     // TODO: Remove this check when we no longer need to support IE
 
-     const stringDataView = this.length() === 0 ?
 
-         emptyDataView() :
 
-         new DataView(this.dataView_.buffer, this.startIndex_, this.length());
 
-     return stringDecoderFunction()(stringDataView);
 
-   }
 
-   /**
 
-    * Returns the buffer as a ByteString.
 
-    * @return {!ByteString}
 
-    */
 
-   asByteString() {
 
-     return byteStringFromUint8ArrayUnsafe(this.asUint8Array());
 
-   }
 
-   /**
 
-    * Returns the DataView as an Uint8Array. DO NOT MODIFY or expose the
 
-    * underlying buffer.
 
-    *
 
-    * @package
 
-    * @return {!Uint8Array}
 
-    */
 
-   asUint8Array() {
 
-     return new Uint8Array(
 
-         this.dataView_.buffer, this.startIndex_, this.length());
 
-   }
 
- }
 
- exports = BufferDecoder;
 
 
  |