1 jls.loader.provide('jls.io.BufferedInputStream');
  2 
  3 jls.loader.require('jls.lang.ByteBuffer');
  4 
  5 jls.io.BufferedInputStream = jls.lang.Class.create( /** @lends jls.io.BufferedInputStream.prototype */
  6 {
  7     /**
  8      * Creates a BufferedInputStream.
  9      * 
 10      * @param {jls.io.InputStream} input The underlying byte input stream.
 11      * @param {Number} size The buffer size.
 12      * @constructs
 13      * @class A character reader for byte input stream.
 14      */
 15     initialize : function(input, size) {
 16         this._in = input;
 17     	this._buffer = jls.lang.ByteBuffer.allocate(size || 1024);
 18         this._buffer.setLimit(0);
 19         this._mark = -1;
 20     },
 21     /**
 22      * Closes this stream.
 23      *
 24      */
 25     close : function() {
 26         return this._in.close();
 27     },
 28     /**
 29      * Flushs this stream.
 30      *
 31      */
 32     flush : function() {
 33         return this._in.flush();
 34     },
 35     mark : function(limit) {
 36         if (this._buffer.remaining() == 0) {
 37             this._buffer.clear();
 38             this._buffer.setLimit(0);
 39         }
 40         if (limit > this._buffer.capacity() - this._buffer.position()) {
 41             throw new jls.lang.BufferOverflowException();
 42         }
 43         this._mark = this._buffer.position();
 44     },
 45     /**
 46      * Tells if this stream supports the mark and reset methods.
 47      * 
 48      * @returns {Boolean} if this stream instance supports the mark and reset methods; false otherwise.
 49      */
 50     markSupported : function() {
 51         return true;
 52     },
 53     reset : function() {
 54         if (this._mark < 0) {
 55             throw new jls.lang.Exception('Invalid mark');
 56         }
 57         this._buffer.setPosition(this._mark);
 58     },
 59     _fill : function() {
 60         if (this._buffer.remaining() > 0) {
 61             return;
 62         }
 63         this._buffer.clear();
 64         this._in.read(this._buffer);
 65         this._mark = -1;
 66     },
 67     /**
 68      * Reads a byte.
 69      * 
 70      * @returns {Number} The unsigned byte or -1.
 71      */
 72     readByte : function() {
 73         this._fill();
 74         return this._buffer.getByte();
 75     },
 76     /**
 77      * Reads bytes into the specified byte array, starting at the given offset.
 78      * 
 79      * @param {ByteArray} barray The destination byte array.
 80      * @param {Number} offset The offset at which to start storing bytes.
 81      * @param {Number} length The maximum number of bytes to read.
 82      * @returns {Number} The total number of bytes read.
 83      */
 84     readByteArray : function(barray, offset, length) {
 85     	offset = offset || 0;
 86     	length = length || barray.size() - offset;
 87         int count = 0;
 88         while (count < length) {
 89             this._fill();
 90             if (this._buffer.remaining() == 0) {
 91                 break;
 92             }
 93             var l = this._buffer.remaining();
 94             if (l > length - count) {
 95                 l = length - count;
 96             }
 97             barray.memcpy(offset + count, this._buffer.byteArray(), this._buffer.position(), l);
 98             buffer.incrementPosition(l);
 99             count += l;
100         }
101         return count;
102     },
103     /**
104      * Reads this file into a buffer.
105      *
106      * @param {jls.lang.Buffer} buffer The buffer to read.
107      * @returns {Number} the read byte count.
108      */
109     read : function(buffer) {
110         int start = buffer.position();
111         while (buffer.remaining() > 0) {
112             this._fill();
113             if (this._buffer.remaining() == 0) {
114                 break;
115             }
116             buffer.putBuffer(this._buffer);
117         }
118         return buffer.position() - start;
119     }
120 });
121 
122