// Generated by IcedCoffeeScript 1.7.1-b
(function() {
  var NativeBuffer, PpBuffer, twos_compl_inv;

  twos_compl_inv = require('./util').twos_compl_inv;

  NativeBuffer = Buffer;

  exports.PpBuffer = PpBuffer = (function() {
    function PpBuffer(buf) {
      if (buf == null) {
        this._frozen_buf = null;
        this._sub_buffers = [];
        this._limits = [];
        this._sz = 0x400;
        this._small_buf_sz = 0x100;
        this._logsz = 10;
        this._i = 0;
        this._tot = 0;
      } else {
        this._freeze_to(buf);
      }
    }

    PpBuffer.prototype._nb = function() {
      return this._sub_buffers.length;
    };

    PpBuffer.prototype._ab = function() {
      return this._sub_buffers[this._nb() - 1];
    };

    PpBuffer.prototype._lib = function() {
      return 0;
    };

    PpBuffer.prototype._finish_sub_buffer = function() {
      this._limits.push(this._i);
      return this._i = 0;
    };

    PpBuffer.prototype._push_sub_buffer = function(b) {
      if (this._sub_buffers.length) {
        this._finish_sub_buffer();
      }
      this._lib = function() {
        return b.length - this._i;
      };
      this._sub_buffers.push(b);
      return b;
    };

    PpBuffer.prototype._make_room = function() {
      return this._push_sub_buffer(new NativeBuffer(this._sz));
    };

    PpBuffer.prototype._make_room_for_n_bytes = function(n) {
      if (this._lib() < n) {
        return this._make_room();
      }
    };

    PpBuffer.prototype.push_uint8 = function(b) {
      var n;
      n = 1;
      this._make_room_for_n_bytes(n);
      this._ab().writeUInt8(b, this._i);
      this._i += n;
      return this._tot += n;
    };

    PpBuffer.prototype.push_int8 = function(b) {
      var n;
      n = 1;
      this._make_room_for_n_bytes(n);
      this._ab().writeInt8(b, this._i);
      this._i += n;
      return this._tot += n;
    };

    PpBuffer.prototype.push_uint16 = function(s) {
      var n;
      n = 2;
      this._make_room_for_n_bytes(n);
      this._ab().writeUInt16BE(s, this._i);
      this._i += n;
      return this._tot += n;
    };

    PpBuffer.prototype.push_uint32 = function(w) {
      var n;
      n = 4;
      this._make_room_for_n_bytes(n);
      this._ab().writeUInt32BE(w, this._i);
      this._i += n;
      return this._tot += n;
    };

    PpBuffer.prototype.push_int16 = function(s) {
      var n;
      n = 2;
      this._make_room_for_n_bytes(n);
      this._ab().writeInt16BE(s, this._i);
      this._i += n;
      return this._tot += n;
    };

    PpBuffer.prototype.push_int32 = function(w) {
      var n;
      n = 4;
      this._make_room_for_n_bytes(n);
      this._ab().writeInt32BE(w, this._i);
      this._i += n;
      return this._tot += n;
    };

    PpBuffer.prototype.push_float64 = function(f) {
      var n;
      n = 8;
      this._make_room_for_n_bytes(n);
      this._ab().writeDoubleBE(f, this._i);
      this._i += n;
      return this._tot += n;
    };

    PpBuffer.prototype.push_float32 = function(f) {
      var n;
      n = 4;
      this._make_room_for_n_bytes(n);
      this._ab().writeFloatBE(f, this._i);
      this._i += n;
      return this._tot += n;
    };

    PpBuffer.prototype.push_raw_bytes = function(s) {
      return this.push_buffer(new NativeBuffer(s, 'binary'));
    };

    PpBuffer.prototype.prepare_utf8 = function(s) {
      return new NativeBuffer(s, 'utf8');
    };

    PpBuffer.prototype.push_buffer = function(b) {
      var diff, n;
      if (b.length > this._small_buf_sz) {
        this._push_sub_buffer(b);
        this._i = b.length;
        this._tot += b.length;
      } else {
        n = Math.min(b.length, this._lib());
        if (n > 0) {
          b.copy(this._ab(), this._i, 0, n);
          this._i += n;
          this._tot += n;
        }
        if (n < b.length) {
          this._make_room();
          b.copy(this._ab(), this._i, n, b.length);
          diff = b.length - n;
          this._i += diff;
          this._tot += diff;
        }
      }
      return this;
    };

    PpBuffer.prototype.freeze = function() {
      var b, i, l, lst, _i, _len, _ref;
      if (this._frozen_buf == null) {
        this._finish_sub_buffer();
        lst = [];
        _ref = this._sub_buffers;
        for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
          b = _ref[i];
          if ((l = this._limits[i]) === b.length) {
            lst.push(b);
          } else if (l > 0) {
            lst.push(b.slice(0, l));
          }
        }
        this._sub_buffers = [];
        this._frozen_buf = NativeBuffer.concat(lst, this._tot);
      }
      return this._frozen_buf;
    };

    PpBuffer.prototype._freeze_to = function(b) {
      this._frozen_buf = b;
      this._tot = b.length;
      this._sub_buffers = [];
      this._cp = 0;
      return this;
    };

    PpBuffer.prototype.bytes_left = function() {
      return this._tot - this._cp;
    };

    PpBuffer.prototype._get = function(i) {
      if (i < this._tot) {
        return this._frozen_buf.readUInt8(i);
      } else {
        return 0;
      }
    };

    PpBuffer.prototype.read_uint8 = function() {
      return this._get(this._cp++);
    };

    PpBuffer.prototype.read_int8 = function() {
      return twos_compl_inv(this.read_uint8(), 8);
    };

    PpBuffer.prototype.read_uint16 = function() {
      var ret;
      ret = this._frozen_buf.readUInt16BE(this._cp);
      this._cp += 2;
      return ret;
    };

    PpBuffer.prototype.read_uint32 = function() {
      var ret;
      ret = this._frozen_buf.readUInt32BE(this._cp);
      this._cp += 4;
      return ret;
    };

    PpBuffer.prototype.read_int16 = function() {
      var ret;
      ret = this._frozen_buf.readInt16BE(this._cp);
      this._cp += 2;
      return ret;
    };

    PpBuffer.prototype.read_int32 = function() {
      var ret;
      ret = this._frozen_buf.readInt32BE(this._cp);
      this._cp += 4;
      return ret;
    };

    PpBuffer.prototype.read_float64 = function() {
      var ret;
      ret = this._frozen_buf.readDoubleBE(this._cp);
      this._cp += 8;
      return ret;
    };

    PpBuffer.prototype.read_float32 = function() {
      var ret;
      ret = this._frozen_buf.readFloatBE(this._cp);
      this._cp += 4;
      return ret;
    };

    PpBuffer.prototype.read_buffer = function(n) {
      var bl, e, ret;
      bl = this.bytes_left();
      if (n > bl) {
        throw new Error("Corruption: asked for " + n + " bytes, but only " + bl + " available");
      }
      e = this._cp + n;
      ret = this._frozen_buf.slice(this._cp, e);
      this._cp = e;
      return ret;
    };

    PpBuffer.isBuffer = function(b) {
      return NativeBuffer.isBuffer(b);
    };

    return PpBuffer;

  })();

}).call(this);
