/**
 * * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Generated by Apache Flex Cross-Compiler from org/apache/flex/utils/BinaryData.as
 * org.apache.flex.utils.BinaryData
 *
 * @fileoverview
 *
 * @suppress {checkTypes|accessControls}
 */

goog.provide('org.apache.flex.utils.BinaryData');

goog.require('org.apache.flex.utils.Endian');
goog.require('org.apache.flex.utils.IBinaryDataInput');
goog.require('org.apache.flex.utils.IBinaryDataOutput');
goog.require('org.apache.flex.utils.Language');



/**
 * @constructor
 * @implements {org.apache.flex.utils.IBinaryDataInput}
 * @implements {org.apache.flex.utils.IBinaryDataOutput}
 * @param {ArrayBuffer=} bytes
 */
org.apache.flex.utils.BinaryData = function(bytes) {
  bytes = typeof bytes !== 'undefined' ? bytes : null;
  
  this._endian = org.apache.flex.utils.Endian.BIG_ENDIAN;
  this._sysEndian = this._endian == org.apache.flex.utils.Endian.systemEndian;
  this.ba = bytes ? bytes : new ArrayBuffer(0);
  this._len = this.ba.byteLength;
};


/**
 *  Utility method to create a BinaryData object from a string.
 *
 *  @asparam {String} str The string to convert to BinaryData as UTF-8 bytes.
 *  @asreturn {BinaryData} The BinaryData instance from the UTF-8 bytes of the string.     *
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.7.0
 * @export
 * @param {string} str
 * @return {org.apache.flex.utils.BinaryData}
 */
org.apache.flex.utils.BinaryData.fromString = function(str) {
  var /** @type {org.apache.flex.utils.BinaryData} */ bd = new org.apache.flex.utils.BinaryData();
  bd.writeUTFBytes(str);
  return bd;
};


/**
 * @private
 * @type {string}
 */
org.apache.flex.utils.BinaryData.prototype._endian;


/**
 * @private
 * @type {boolean}
 */
org.apache.flex.utils.BinaryData.prototype._sysEndian;


/**
 * @private
 * @type {ArrayBuffer}
 */
org.apache.flex.utils.BinaryData.prototype.ba;


/**
 * @private
 * @type {number}
 */
org.apache.flex.utils.BinaryData.prototype._position = 0;


/**
 *  Write a Boolean value (as a single byte) at the current position
 *
 *  @asparam {Boolean} value The boolean value to write into the BinaryData at the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {boolean} value
 */
org.apache.flex.utils.BinaryData.prototype.writeBoolean = function(value) {
  
  this.writeByte(value ? 1 : 0);
};


/**
 *  Write a byte of binary data at the current position
 *
 *  @asparam {int} byte The value to write into the BinaryData at the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {number} byte
 */
org.apache.flex.utils.BinaryData.prototype.writeByte = function(byte) {
  
  if (this._position + 1 > this._len) {
    this.setBufferSize(this._position + 1);
  }
  new Uint8Array(this.ba, this._position, 1)[0] = byte;
  this._position++;
};


/**
 *  Writes a sequence of <code>length</code> bytes from the <code>source</code> BinaryData, starting
 *  at <code>offset</code> (zero-based index) bytes into the source BinaryData. If length
 *  is omitted or is zero, it will represent the entire length of the source
 *  starting from offset. If offset is omitted also, it defaults to zero.
 *
 *  @asparam {BinaryData} source The source BinaryData to write from at the current position
 *  @asparam {uint} offset The optional offset value of the starting bytes to write inside source
 *  @asparam {uint} length The optional length value of the bytes to write from offset in source
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {org.apache.flex.utils.BinaryData} source
 * @param {number=} offset
 * @param {number=} length
 */
org.apache.flex.utils.BinaryData.prototype.writeBytes = function(source, offset, length) {
  offset = typeof offset !== 'undefined' ? offset : 0;
  length = typeof length !== 'undefined' ? length : 0;
  
  if (length == 0)
    length = source.length - offset;
  if (this._position + length > this._len) {
    this.setBufferSize(this._position + length);
  }
  var /** @type {Uint8Array} */ dest = new Uint8Array(this.ba, this._position, length);
  var /** @type {Uint8Array} */ src = new Uint8Array(source.ba, offset, length);
  dest.set(src);
  this._position += length;
};


/**
 *  Write a short integer (16 bits, typically represented by a 32 bit int parameter between -32768 and 65535)
 *  of binary data at the current position
 *
 *  @asparam {int} short The value to write into the BinaryData at the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {number} short
 */
org.apache.flex.utils.BinaryData.prototype.writeShort = function(short) {
  
  if (!this._sysEndian) {
    short = (((short & 0xff00) >>> 8) | ((short & 0xff) << 8));
  }
  if (this._position + 2 > this._len) {
    this.setBufferSize(this._position + 2);
  }
  new Int16Array(this.ba, this._position, 1)[0] = short;
  this._position += 2;
};


/**
 *  Write an unsigned int (32 bits) of binary data at the current position
 *
 *  @asparam {uint} val The value to write into the BinaryData at the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {number} val
 */
org.apache.flex.utils.BinaryData.prototype.writeUnsignedInt = function(val) {
  
  if (!this._sysEndian) {
    val = ((val & 0xff000000) >>> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | (val << 24);
  }
  if (this._position + 4 > this._len) {
    this.setBufferSize(this._position + 4);
  }
  new Uint32Array(this.ba, this._position, 1)[0] = val;
  this._position += 4;
};


/**
 *  Write a signed int (32 bits) of binary data at the current position
 *
 *  @asparam {int} val The value to write into the BinaryData at the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {number} val
 */
org.apache.flex.utils.BinaryData.prototype.writeInt = function(val) {
  
  if (!this._sysEndian) {
    val = (((val & 0xff000000) >>> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | (val << 24)) >> 0;
  }
  if (this._position + 4 > this._len) {
    this.setBufferSize(this._position + 4);
  }
  new Int32Array(this.ba, this._position, 1)[0] = val;
  this._position += 4;
};


/**
 *  Writes an IEEE 754 single-precision (32-bit) floating-point number to the
 *  BinaryData at the current position
 *
 *  @asparam {Number} val The value to write into the BinaryData at the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {number} val
 */
org.apache.flex.utils.BinaryData.prototype.writeFloat = function(val) {
  
  if (this._position + 4 > this._len) {
    this.setBufferSize(this._position + 4);
  }
  if (this._sysEndian) {
    new Float32Array(this.ba, this._position, 1)[0] = val;
  } else {
    new DataView(this.ba).setFloat32(this._position, val, this._endian == org.apache.flex.utils.Endian.LITTLE_ENDIAN);
  }
  this._position += 4;
};


/**
 *  Writes an IEEE 754 double-precision (64-bit) floating-point number to the
 *  BinaryData at the current position
 *
 *  @asparam {Number} val The value to write into the BinaryData at the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {number} val
 */
org.apache.flex.utils.BinaryData.prototype.writeDouble = function(val) {
  
  if (this._position + 8 > this._len) {
    this.setBufferSize(this._position + 8);
  }
  if (this._sysEndian)
    new Float64Array(this.ba, this._position, 1)[0] = val;
  else
    new DataView(this.ba).setFloat64(this._position, val, this._endian == org.apache.flex.utils.Endian.LITTLE_ENDIAN);
  this._position += 8;
};


/**
 *  Reads a Boolean value (as a single byte) at the current position.
 *  returns true if the byte was non-zero, false otherwise
 *
 *  @asreturn {Boolean} The boolean value read from the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @return {boolean}
 */
org.apache.flex.utils.BinaryData.prototype.readBoolean = function() {
  
  return Boolean(this.readUnsignedByte());
};


/**
 *  Read a signed byte of binary data at the current position
 *
 *  @asreturn {int} An int value in the range -128 to 127, read from the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @return {number}
 */
org.apache.flex.utils.BinaryData.prototype.readByte = function() {
  
  var /** @type {Int8Array} */ view = new Int8Array(this.ba, this._position, 1);
  this._position++;
  return view[0];
};


/**
 *  Read an unsigned byte of binary data at the current position
 *
 *  @asreturn {uint} An uint value in the range 0 to 255, read from the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @return {number}
 */
org.apache.flex.utils.BinaryData.prototype.readUnsignedByte = function() {
  
  var /** @type {Uint8Array} */ view = new Uint8Array(this.ba, this._position, 1);
  this._position++;
  return view[0];
};


/**
 *  Reads the number of data bytes, specified by the length parameter, from the BinaryData.
 *  The bytes are read into the BinaryData object specified by the destination parameter,
 *  and the bytes are written into the destination BinaryData starting at the position specified by offset.
 *  If length is omitted or is zero, all bytes are read following the current position to the end
 *  of this BinaryData. If offset is also omitted, it defaults to zero.
 *
 *  @asparam {BinaryData} destination The destination BinaryData to write bytes into from the current position
 *  @asparam {uint} offset The optional offset value of the starting bytes to write inside destination
 *  @asparam {uint} length The optional length value of the bytes to read
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {org.apache.flex.utils.BinaryData} destination
 * @param {number=} offset
 * @param {number=} length
 */
org.apache.flex.utils.BinaryData.prototype.readBytes = function(destination, offset, length) {
  offset = typeof offset !== 'undefined' ? offset : 0;
  length = typeof length !== 'undefined' ? length : 0;
  
  if (length == 0)
    length = this._len - this._position;
  var /** @type {number} */ extra = offset + length - destination._len;
  if (extra > 0)
    destination.growBuffer(extra);
  var /** @type {Uint8Array} */ src = new Uint8Array(this.ba, this._position, length);
  var /** @type {Uint8Array} */ dest = new Uint8Array(destination.ba, offset, length);
  dest.set(src);
  this._position += length;
};


/**
 *  Read a byte of binary data at the specified index. Does not change the <code>position</code> property.
 *  If an index is out of range (beyond the current length) this will return zero.
 *
 *  @asreturn {uint} A byte value in the range 0-255 from the index
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {number} idx
 * @return {number}
 */
org.apache.flex.utils.BinaryData.prototype.readByteAt = function(idx) {
  
  return this.getTypedArray()[idx] >> 0;
};


/**
 * @private
 * @type {Uint8Array}
 */
org.apache.flex.utils.BinaryData.prototype._typedArray;


/**
 * @private
 * @return {Uint8Array}
 */
org.apache.flex.utils.BinaryData.prototype.getTypedArray = function() {
  if (this._typedArray == null)
    this._typedArray = new Uint8Array(this.ba);
  return this._typedArray;
};


/**
 *  Writes a byte of binary data at the specified index. Does not change the <code>position</code> property.
 *  This is a method for optimzed writes with no range checking.
 *  If the specified index is out of range, it can throw an error.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {number} idx
 * @param {number} byte
 */
org.apache.flex.utils.BinaryData.prototype.writeByteAt = function(idx, byte) {
  
  if (idx >= this._len) {
    this.setBufferSize(idx + 1);
  }
  this.getTypedArray()[idx] = byte;
};


/**
 *  Read a short int of binary data at the current position
 *
 *  @asreturn {int} An int value in the range -32768 to 32767, read from the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @return {number}
 */
org.apache.flex.utils.BinaryData.prototype.readShort = function() {
  
  var /** @type {number} */ ret = Number(new Int16Array(this.ba, this._position, 1)[0]);
  if (!this._sysEndian) {
    ret = ((((ret & 0xff00) >> 8) | ((ret & 0xff) << 8)) << 16) >> 16;
  }
  this._position += 2;
  return ret;
};


/**
 *  Read an unsigned int (32bit) of binary data at the current position
 *
 *  @asreturn {uint} A uint value, read from the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @return {number}
 */
org.apache.flex.utils.BinaryData.prototype.readUnsignedInt = function() {
  
  var /** @type {number} */ ret = Number(new Uint32Array(this.ba, this._position, 1)[0]);
  if (!this._sysEndian) {
    ret = (((ret & 0xff000000) >>> 24) | ((ret & 0x00ff0000) >>> 8) | ((ret & 0x0000ff00) << 8) | (ret << 24)) >>> 0;
  }
  this._position += 4;
  return ret;
};


/**
 *  Read an unsigned short (16bit) of binary data at the current position
 *
 *  @asreturn {uint} A uint value in the range 0 to 65535, read from the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @return {number}
 */
org.apache.flex.utils.BinaryData.prototype.readUnsignedShort = function() {
  
  var /** @type {number} */ ret = Number(new Uint16Array(this.ba, this._position, 1)[0]);
  if (!this._sysEndian) {
    ret = ((ret & 0xff00) >> 8) | ((ret & 0xff) << 8);
  }
  this._position += 2;
  return ret;
};


/**
 *  Read a signed int (32bit) of binary data at the current position
 *
 *  @asreturn {int} An int value, read from the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @return {number}
 */
org.apache.flex.utils.BinaryData.prototype.readInt = function() {
  
  var /** @type {number} */ ret = Number(new Int32Array(this.ba, this._position, 1)[0]);
  if (!this._sysEndian) {
    ret = (((ret & 0xff000000) >>> 24) | ((ret & 0x00ff0000) >>> 8) | ((ret & 0x0000ff00) << 8) | (ret << 24)) >> 0;
  }
  this._position += 4;
  return ret;
};


/**
 *  Reads an IEEE 754 single-precision (32-bit) floating-point number from the BinaryData.
 *
 *  @asreturn {Number} A Number value, read from the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @return {number}
 */
org.apache.flex.utils.BinaryData.prototype.readFloat = function() {
  
  var /** @type {number} */ ret;
  if (this._sysEndian) {
    ret = Number(new Float32Array(this.ba, this._position, 1)[0]);
  }
  else
    ret = new DataView(this.ba).getFloat32(this._position, this._endian == org.apache.flex.utils.Endian.LITTLE_ENDIAN);
  this._position += 4;
  return ret;
};


/**
 *  Reads an IEEE 754 double-precision (64-bit) floating-point number from the BinaryData.
 *
 *  @asreturn {Number} A Number value, read from the current position
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @return {number}
 */
org.apache.flex.utils.BinaryData.prototype.readDouble = function() {
  
  var /** @type {number} */ ret;
  if (this._sysEndian)
    ret = Number(new Float64Array(this.ba, this._position, 1)[0]);
  else
    ret = new DataView(this.ba).getFloat64(this._position, this._endian == org.apache.flex.utils.Endian.LITTLE_ENDIAN);
  this._position += 8;
  return ret;
};


/**
 * @private
 * @type {number}
 */
org.apache.flex.utils.BinaryData.prototype._len;


/**
 * @protected
 * @param {*} newSize
 */
org.apache.flex.utils.BinaryData.prototype.setBufferSize = function(newSize) {
  var /** @type {number} */ n = this._len;
  if (n != newSize) {
    var /** @type {Uint8Array} */ newView = new Uint8Array(newSize);
    var /** @type {Uint8Array} */ oldView = new Uint8Array(this.ba, 0, Math.min(newSize, n));
    newView.set(oldView);
    this.ba = newView.buffer;
    if (this._position > newSize)
      this._position = Number(newSize);
    this._typedArray = newView;
    this._len = Number(newSize);
  }
};


/**
 *  A convenience method to extend the length of the BinaryData
 *  so you can efficiently write more bytes to it. Not all
 *  browsers have a way to auto-resize a binary
 *  data as you write data to the binary data buffer
 *  and resizing in large chunks is generally more
 *  efficient anyway. Preallocating bytes to write into
 *  is also more efficient on the swf target.
 *
 *  @asparam extra The number of additional bytes.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.0
 * @export
 * @param {number} extra
 */
org.apache.flex.utils.BinaryData.prototype.growBuffer = function(extra) {
  
  this.setBufferSize(this._len + extra);
};


/**
 *  Reads a UTF-8 string from the BinaryData.
 *  The string is assumed to be prefixed with an unsigned short indicating the length in bytes.
 *  The <code>position</code> is advanced to the first byte following the string's bytes.
 *
 *  @asreturn {String} The utf-8 decoded string
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.7.0
 * @export
 * @return {string}
 */
org.apache.flex.utils.BinaryData.prototype.readUTF = function() {
  
  var /** @type {number} */ bytes = this.readUnsignedShort();
  return this.readUTFBytes(bytes);
};


/**
 *  Reads a sequence of UTF-8 bytes specified by the length parameter
 *  from the BinaryData and returns a string.
 *  The <code>position</code> is advanced to the first byte following the string's bytes.
 *
 *  @asparam {uint} length An unsigned short indicating the length of the UTF-8 bytes.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.7.0
 * @export
 * @param {number} length
 * @return {string}
 */
org.apache.flex.utils.BinaryData.prototype.readUTFBytes = function(length) {
  
  var /** @type {Uint8Array} */ bytes = new Uint8Array(this.ba, this._position, length);
  if ('TextDecoder' in window) {
    var /** @type {TextDecoder} */ decoder = new TextDecoder('utf-8');
    this._position += length;
    return decoder.decode(bytes);
  }
  var /** @type {Array} */ out = [];
  var /** @type {number} */ pos = 0;
  var /** @type {number} */ c = 0;
  var /** @type {number} */ c1;
  var /** @type {number} */ c2;
  var /** @type {number} */ c3;
  var /** @type {number} */ c4;
  while (pos < bytes.length) {
    c1 = Number(bytes[pos++]);
    if (c1 < 128) {
      out[c++] = String.fromCharCode(c1);
    } else if (c1 > 191 && c1 < 224) {
      c2 = Number(bytes[pos++]);
      out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63);
    } else if (c1 > 239 && c1 < 365) {
      c2 = Number(bytes[pos++]);
      c3 = Number(bytes[pos++]);
      c4 = Number(bytes[pos++]);
      var /** @type {number} */ u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) - 0x10000;
      out[c++] = String.fromCharCode(0xD800 + (u >> 10));
      out[c++] = String.fromCharCode(0xDC00 + (u & 1023));
    } else {
      c2 = Number(bytes[pos++]);
      c3 = Number(bytes[pos++]);
      out[c++] = String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
    }
  }
  this._position += length;
  return out.join('');
};


/**
 *  Writes a UTF-8 string to the byte stream.
 *  The length of the UTF-8 string in bytes is written first, as a 16-bit unsigned integer,
 *  followed by the bytes representing the characters of the string.
 *  If the byte length of the string is larger than 65535 this will throw a RangeError
 *  The <code>position</code> is advanced to the first byte following the string's bytes.
 *
 *  @asparam {String} str The string value to be written.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.7.0
 * @export
 * @param {string} str
 */
org.apache.flex.utils.BinaryData.prototype.writeUTF = function(str) {
  
  var /** @type {Uint8Array} */ utcBytes = this.getUTFBytes(str, true);
  this._position = this.mergeInToArrayBuffer(this._position, utcBytes);
};


/**
 *  Writes a UTF-8 string to the BinaryData. Similar to the writeUTF() method,
 *  but writeUTFBytes() does not prefix the string with a 16-bit length word, and
 *  therefore also permits strings longer than 65535 bytes (note: byte length will not
 *  necessarily be the same as string length because some characters can be
 *  multibyte characters).
 *
 *  @asparam {String} str The string value to be written.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10.2
 *  @playerversion AIR 2.6
 *  @productversion FlexJS 0.7.0
 * @export
 * @param {string} str
 */
org.apache.flex.utils.BinaryData.prototype.writeUTFBytes = function(str) {
  
  var /** @type {Uint8Array} */ utcBytes = this.getUTFBytes(str, false);
  this._position = this.mergeInToArrayBuffer(this._position, utcBytes);
};


/**
 * @private
 * @param {number} offset
 * @param {Uint8Array} newBytes
 * @return {number}
 */
org.apache.flex.utils.BinaryData.prototype.mergeInToArrayBuffer = function(offset, newBytes) {
  var /** @type {number} */ newContentLength = newBytes.length;
  var /** @type {Uint8Array} */ dest;
  if (offset + newContentLength > this._len) {
    dest = new Uint8Array(offset + newContentLength);
    dest.set(new Uint8Array(this.ba, 0, offset));
    dest.set(newBytes, offset);
    this.ba = dest.buffer;
    this._typedArray = dest;
  } else {
    dest = new Uint8Array(this.ba, offset, newContentLength);
    dest.set(newBytes);
  }
  return offset + newContentLength;
};


/**
 * @private
 * @param {string} str
 * @param {boolean} prependLength
 * @return {Uint8Array}
 */
org.apache.flex.utils.BinaryData.prototype.getUTFBytes = function(str, prependLength) {
  var /** @type {Uint8Array} */ bytes;
  if ('TextEncoder' in window) {
    var /** @type {TextEncoder} */ encoder = new TextEncoder('utf-8');
    bytes = encoder.encode(str);
  } else {
    var /** @type {Array} */ out = [];
    var /** @type {number} */ p = 0;
    var /** @type {number} */ c;
    for (var /** @type {number} */ i = 0; i < str.length; i++) {
      c = str.charCodeAt(i);
      if (c < 128) {
        out[p++] = c;
      } else if (c < 2048) {
        out[p++] = (c >> 6) | 192;
        out[p++] = (c & 63) | 128;
      } else if (((c & 0xFC00) == 0xD800) && (i + 1) < str.length && ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {
        c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);
        out[p++] = (c >> 18) | 240;
        out[p++] = ((c >> 12) & 63) | 128;
        out[p++] = ((c >> 6) & 63) | 128;
        out[p++] = (c & 63) | 128;
      } else {
        out[p++] = (c >> 12) | 224;
        out[p++] = ((c >> 6) & 63) | 128;
        out[p++] = (c & 63) | 128;
      }
    }
    bytes = new Uint8Array(out);
  }
  if (prependLength) {
    var /** @type {number} */ len = bytes.length;
    if (len > 0xffff) {
      throw new RangeError("UTF max string length of 65535 bytes exceeded : BinaryData.writeUTF");
    }
    var /** @type {Uint8Array} */ temp = new Uint8Array(bytes.length + 2);
    temp.set(bytes, 2);
    new Uint16Array(temp.buffer, 0, 1)[0] = this._sysEndian ? len : (((len & 0xff00) >> 8) | ((len & 0xff) << 8));
    bytes = temp;
  }
  return bytes;
};


Object.defineProperties(org.apache.flex.utils.BinaryData.prototype, /** @lends {org.apache.flex.utils.BinaryData.prototype} */ {
/** @export */
array: {
get: /** @this {org.apache.flex.utils.BinaryData} */ function() {
  return this.getTypedArray();
}},
/** @export */
endian: {
get: /** @this {org.apache.flex.utils.BinaryData} */ function() {
  
  return this._endian;
},
set: /** @this {org.apache.flex.utils.BinaryData} */ function(value) {
  if (value == org.apache.flex.utils.Endian.BIG_ENDIAN || org.apache.flex.utils.Endian.LITTLE_ENDIAN) {
    this._endian = value;
    this._sysEndian = value == org.apache.flex.utils.Endian.systemEndian;
    
  }
}},
/** @export */
data: {
get: /** @this {org.apache.flex.utils.BinaryData} */ function() {
  return this.ba;
}},
/** @export */
length: {
get: /** @this {org.apache.flex.utils.BinaryData} */ function() {
  
  return this._len;
},
set: /** @this {org.apache.flex.utils.BinaryData} */ function(value) {
  
  this.setBufferSize(value);
}},
/** @export */
bytesAvailable: {
get: /** @this {org.apache.flex.utils.BinaryData} */ function() {
  
  return this._position < this._len ? this._len - this._position : 0;
}},
/** @export */
position: {
get: /** @this {org.apache.flex.utils.BinaryData} */ function() {
  
  return this._position;
},
set: /** @this {org.apache.flex.utils.BinaryData} */ function(value) {
  
  this._position = value;
}}}
);


/**
 * Metadata
 *
 * @type {Object.<string, Array.<Object>>}
 */
org.apache.flex.utils.BinaryData.prototype.FLEXJS_CLASS_INFO = { names: [{ name: 'BinaryData', qName: 'org.apache.flex.utils.BinaryData'}], interfaces: [org.apache.flex.utils.IBinaryDataInput, org.apache.flex.utils.IBinaryDataOutput] };


/**
 * Prevent renaming of class. Needed for reflection.
 */
goog.exportSymbol('org.apache.flex.utils.BinaryData', org.apache.flex.utils.BinaryData);



/**
 * Reflection
 *
 * @return {Object.<string, Function>}
 */
org.apache.flex.utils.BinaryData.prototype.FLEXJS_REFLECTION_INFO = function () {
  return {
    variables: function () {
      return {
      };
    },
    accessors: function () {
      return {
        'array': { type: 'Uint8Array', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'endian': { type: 'String', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'data': { type: 'Object', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'length': { type: 'int', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'bytesAvailable': { type: 'uint', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'position': { type: 'uint', declaredBy: 'org.apache.flex.utils.BinaryData'}
      };
    },
    methods: function () {
      return {
        'BinaryData': { type: '', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'writeBoolean': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'writeByte': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'writeBytes': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'writeShort': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'writeUnsignedInt': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'writeInt': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'writeFloat': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'writeDouble': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readBoolean': { type: 'Boolean', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readByte': { type: 'int', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readUnsignedByte': { type: 'uint', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readBytes': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readByteAt': { type: 'uint', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'writeByteAt': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readShort': { type: 'int', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readUnsignedInt': { type: 'uint', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readUnsignedShort': { type: 'uint', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readInt': { type: 'int', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readFloat': { type: 'Number', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readDouble': { type: 'Number', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'growBuffer': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readUTF': { type: 'String', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'readUTFBytes': { type: 'String', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'writeUTF': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'},
        'writeUTFBytes': { type: 'void', declaredBy: 'org.apache.flex.utils.BinaryData'}
      };
    }
  };
};