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() >>> 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.Buffer.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.Buffer.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 // TODO wrap + memcpy? 124 for (var i = 0; i < s.length; i++) { 125 this.putChar(s.charCodeAt(i)); 126 } 127 return this; 128 }, 129 getString : function(length) { 130 if (length) { 131 if (this.remaining() < length) { 132 throw new jls.lang.BufferUnderflowException(); 133 } 134 } else { 135 length = this.remaining(); 136 } 137 /*var value = ''; 138 while (--length >= 0) { 139 value += String.fromCharCode(this.getChar()); 140 }*/ 141 var value = this._barray.getChars(this.position(), length); 142 this._position += length; 143 return value; 144 }, 145 putBuffer : function(buffer, length) { 146 length = length || buffer.remaining(); 147 if (this.remaining() < length) { 148 throw new jls.lang.BufferOverflowException(); 149 } 150 this._barray.memcpy(this.offset() * 2, buffer.byteArray(), buffer.position() * 2, length * 2); 151 this._position += length; 152 buffer.incrementPosition(length); 153 return this; 154 }, 155 toNewString : function(length) { 156 length = length || this.limit(); 157 if (this.getOffset() != 0) { 158 throw new jls.lang.Exception('Invalid CharBuffer (offset != 0)'); 159 } 160 return this._barray.toNewChars(length); 161 }, 162 toString : function() { 163 return this.getString(); 164 } 165 }); 166 167 Object.extend(jls.lang.CharBuffer, /** @lends jls.lang.CharBuffer */ 168 { 169 /** 170 * Allocates a new buffer. 171 * 172 * @param {Number} capacity The capacity of the character buffer. 173 * @returns {jls.lang.Buffer} The new buffer. 174 */ 175 allocate : function(capacity, adoptable) { 176 return jls.lang.CharBuffer.wrap(new _native.core.ByteArray((capacity + 1) * 2, adoptable)); 177 }, 178 /** 179 * Wraps an existing native byte array into a new character buffer. 180 * 181 * @param {_native.core.ByteArray} barray The native byte array to wrap. 182 * @param {Number} offset The offset of the byte array to use for this buffer. 183 * @param {Number} length The length of the buffer. 184 * @returns {jls.lang.Buffer} The new buffer. 185 */ 186 wrap : function(barray, offset, length) { 187 if (typeof barray == 'string') { 188 length = length || barray.length; 189 //jls.logger.trace('CharBuffer.wrap("' + barray + '")'); 190 barray = new _native.core.ByteArray(barray); 191 //jls.logger.trace('CharBuffer.wrap(), barray.size(): ' + barray.size()); 192 var buffer = new jls.lang.CharBuffer(barray, offset, length); 193 //jls.logger.trace('CharBuffer.wrap(), buffer.remaining(): ' + buffer.remaining() + ', buffer.capacity(): ' + buffer.capacity()); 194 return buffer; 195 } 196 return new jls.lang.CharBuffer(barray, offset, length); 197 }, 198 // Byte order constants. 199 DEFAULT_BYTE_ORDER : jls.lang.Buffer.LITTLE_ENDIAN 200 }); 201 202