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