1 jls.loader.provide('jls.lang.CharBuffer');
  2 
  3 jls.loader.require('jls.lang.Buffer');
  4 jls.loader.require('jls.lang.ByteBuffer');
  5 jls.loader.require('jls.lang.IllegalArgumentException');
  6 jls.loader.require('jls.lang.BufferOverflowException');
  7 jls.loader.require('jls.lang.BufferUnderflowException');
  8 
  9 /**
 10  * @augments jls.lang.Buffer
 11  * @class The buffer class provides facilities to get and put datas from/to a native string.
 12  */
 13 jls.lang.CharBuffer = jls.lang.Class.create(jls.lang.Buffer, /** @lends jls.lang.CharBuffer.prototype */
 14 {
 15     initialize : function($super, barray, offset, length, limit, position) {
 16         if (! (barray instanceof _native.core.ByteArray)) {
 17             throw new jls.lang.Exception('Invalid barray argument (' + (typeof barray) + ')');
 18         }
 19         this._barray = barray;
 20         offset = offset || 0;
 21         var capacity = (typeof length != 'undefined') ? length : this._barray.size() / 2 - 1 - offset;
 22         $super(capacity, limit, position, offset);
 23         this._byteOrder = jls.lang.CharBuffer.DEFAULT_BYTE_ORDER;
 24     },
 25     /**
 26      * Returns the native byte array of this buffer.
 27      * 
 28      * @returns {_native.core.ByteArray} The native byte array.
 29      */
 30     byteArray : function() {
 31         return this._barray;
 32     },
 33     /**
 34      * Free the associated byte array.
 35      * 
 36      * @returns {jls.lang.Buffer} This buffer.
 37      */
 38     free : function() {
 39         this._barray.free();
 40         return this;
 41     },
 42     /**
 43      * Creates a new buffer sharing the native string.
 44      * 
 45      * @returns {jls.lang.Buffer} The new buffer.
 46      */
 47     duplicate : function() {
 48         return new jls.lang.CharBuffer(this._barray, this._offset, this._capacity, this._limit, this._position);
 49     },
 50     /**
 51      * Creates a new buffer starting at the current position and with the remaining character.
 52      * 
 53      * @returns {jls.lang.Buffer} The new buffer.
 54      */
 55     slice : function() {
 56         return new jls.lang.CharBuffer(this._barray, this.position(), this.remaining());
 57     },
 58     /**
 59      * Puts a character into this buffer at the current position, and then increments the position.
 60      * 
 61      * @param {Number} c The character code to put.
 62      * @returns {jls.lang.Buffer} This buffer.
 63      */
 64     putChar : function(c) {
 65         if (this.remaining() < 1) {
 66             throw new jls.lang.BufferOverflowException();
 67         }
 68         if (typeof c == 'string') {
 69         	if (c.length != 1) {
 70                 throw new jls.lang.Exception('Invalid character argument');
 71         	}
 72         	c = c.charCodeAt(0);
 73         }
 74         var os = this.offset() * 2;
 75         if (this._byteOrder == jls.lang.ByteBuffer.BIG_ENDIAN) {
 76             this._barray.put(os, (c >> 8) & 0xff);
 77             this._barray.put(os + 1, c & 0xff);
 78         } else {
 79             this._barray.put(os, c & 0xff);
 80             this._barray.put(os + 1, (c >> 8) & 0xff);
 81         }
 82         this._position++;
 83         return this;
 84     },
 85     /**
 86      * Gets a character from this buffer at a specified position.
 87      * 
 88      * @param {Number} index The position of the character to read.
 89      * @returns {Number} The character code.
 90      */
 91     getCharAt : function(index) {
 92         if (index > this.limit()) {
 93             throw new jls.lang.Exception('Index out of bound');
 94         }
 95         var value;
 96         var os = (this.getOffset() + index) * 2;
 97         if (this._byteOrder == jls.lang.ByteBuffer.BIG_ENDIAN) {
 98             value = this._barray.get(os) << 8;
 99             value |= this._barray.get(os + 1);
100         } else {
101             value = this._barray.get(os);
102             value |= this._barray.get(os + 1) << 8;
103         }
104         return value;
105     },
106     /**
107      * Gets a character from this buffer at the current position, and then increments the position.
108      * 
109      * @returns {Number} The character code.
110      */
111     getChar : function() {
112         if (this.remaining() < 1) {
113             throw new jls.lang.BufferUnderflowException();
114         }
115         var value = this.getCharAt(this.position());
116         this._position++;
117         return value;
118     },
119     putString : function(s) {
120         if (this.remaining() < s.length) {
121             throw new jls.lang.BufferOverflowException();
122         }
123     	for (var i = 0; i < s.length; i++) {
124     		this.putChar(s.charCodeAt(i));
125     	}
126         return this;
127     },
128     getString : function(length) {
129         if (length) {
130             if (this.remaining() < length) {
131                 throw new jls.lang.BufferUnderflowException();
132             }
133         } else {
134             length = this.remaining();
135         }
136         var value = '';
137     	while (--length >= 0) {
138     		value += String.fromCharCode(this.getChar());
139     	}
140         return value;
141     },
142     putBuffer : function(buffer, length) {
143 		length = length || buffer.remaining();
144         if (this.remaining() < length) {
145             throw new jls.lang.BufferOverflowException();
146         }
147         this._barray.memcpy(this.offset() * 2, buffer.byteArray(), buffer.position() * 2, length * 2);
148         this._position += length;
149         //buffer.incrementPosition(length);
150         return this;
151     },
152     toNewString : function() {
153     	if (this.getOffset() != 0) {
154             throw new jls.lang.Exception('Invalid CharBuffer (offset != 0)');
155     	}
156         return this._barray.toNewChars(this.limit());
157     },
158     toString : function() {
159         return this.getString();
160     }
161 });
162 
163 Object.extend(jls.lang.CharBuffer, /** @lends jls.lang.CharBuffer */
164 {
165     /**
166      * Allocates a new buffer.
167      * 
168      * @param {Number} capacity The capacity of the character buffer.
169      * @returns {jls.lang.Buffer} The new buffer.
170      */
171     allocate : function(capacity, adoptable) {
172         return jls.lang.CharBuffer.wrap(new _native.core.ByteArray((capacity + 1) * 2, adoptable));
173     },
174     /**
175      * Wraps an existing native byte array into a new character buffer.
176      * 
177      * @param {_native.core.ByteArray} barray The native byte array to wrap.
178      * @param {Number} offset The offset of the byte array to use for this buffer.
179      * @param {Number} length The length of the buffer.
180      * @returns {jls.lang.Buffer} The new buffer.
181      */
182     wrap : function(barray, offset, length) {
183         if (typeof barray == 'string') {
184         	barray = new _native.core.ByteArray(barray);
185         }
186         return new jls.lang.CharBuffer(barray, offset, length);
187     },
188     // Byte order constants.
189     DEFAULT_BYTE_ORDER : jls.lang.ByteBuffer.LITTLE_ENDIAN
190 });
191 
192