1 30 package org.jruby.util; 31 32 import java.io.Serializable ; 33 34 35 39 public class ByteList implements Comparable , CharSequence , Serializable { 40 private static final long serialVersionUID = -1286166947275543731L; 41 42 public static final byte[] NULL_ARRAY = new byte[0]; 43 44 public byte[] bytes; 45 public int realSize; 46 47 private static final int DEFAULT_SIZE = 4; 48 private static final double FACTOR = 1.5; 49 50 51 public ByteList() { 52 this(DEFAULT_SIZE); 53 } 54 55 public ByteList(int size) { 56 bytes = new byte[size]; 57 realSize = 0; 58 } 59 60 public ByteList(byte[] wrap) { 61 this(wrap,true); 62 } 63 64 public ByteList(byte[] wrap, boolean copy) { 65 if (wrap == null) throw new NullPointerException ("Invalid argument: constructing with null array"); 66 if(copy) { 67 bytes = (byte[])wrap.clone(); 68 } else { 69 bytes = wrap; 70 } 71 realSize = wrap.length; 72 } 73 74 public ByteList(ByteList wrap) { 75 this(wrap.bytes, 0, wrap.realSize); 76 } 77 78 public ByteList(byte[] wrap, int index, int len) { 79 this(wrap,index,len,true); 80 } 81 82 public ByteList(byte[] wrap, int index, int len, boolean copy) { 83 if (wrap == null) throw new NullPointerException ("Invalid argument: constructing with null array"); 84 if(copy || index != 0) { 85 bytes = new byte[len]; 86 System.arraycopy(wrap, index, bytes, 0, len); 87 } else { 88 bytes = wrap; 89 } 90 realSize = len; 91 } 92 93 public ByteList(ByteList wrap, int index, int len) { 94 this(wrap.bytes, index, len); 95 } 96 97 public void delete(int start, int len) { 98 realSize-=len; 99 System.arraycopy(bytes,start+len,bytes,start,realSize); 100 } 101 102 public void append(byte b) { 103 grow(1); 104 bytes[realSize++] = b; 105 } 106 107 public void append(int b) { 108 append((byte)b); 109 } 110 111 public void prepend(byte b) { 112 grow(1); 113 System.arraycopy(bytes, 0, bytes, 1, realSize); 114 bytes[0] = b; 115 realSize++; 116 } 117 118 public void append(byte[] moreBytes) { 119 grow(moreBytes.length); 120 System.arraycopy(moreBytes, 0, bytes, realSize, moreBytes.length); 121 realSize += moreBytes.length; 122 } 123 124 public void append(ByteList moreBytes) { 125 append(moreBytes.bytes, 0, moreBytes.realSize); 126 } 127 128 public void append(ByteList moreBytes, int index, int len) { 129 append(moreBytes.bytes, index, len); 130 } 131 132 public void append(byte[] moreBytes, int start, int len) { 133 grow(len); 134 System.arraycopy(moreBytes, start, bytes, realSize, len); 135 realSize += len; 136 } 137 138 public int length() { 139 return realSize; 140 } 141 142 public void length(int newLength) { 143 grow(newLength - realSize); 144 realSize = newLength; 145 } 146 147 public int get(int index) { 148 if (index >= realSize) throw new IndexOutOfBoundsException (); 149 return bytes[index]; 150 } 151 152 public void set(int index, int b) { 153 if (index >= realSize) throw new IndexOutOfBoundsException (); 154 bytes[index] = (byte)b; 155 } 156 157 public void replace(byte[] newBytes) { 158 if (newBytes == null) throw new NullPointerException ("Invalid argument: replacing with null array"); 159 this.bytes = newBytes; 160 realSize = newBytes.length; 161 } 162 163 167 public void unsafeReplace(int beg, int len, ByteList nbytes) { 168 unsafeReplace(beg, len, nbytes.bytes, 0, nbytes.realSize); 169 } 170 171 175 public void unsafeReplace(int beg, int len, byte[] buf) { 176 unsafeReplace(beg, len, buf, 0, buf.length); 177 } 178 179 183 public void unsafeReplace(int beg, int len, byte[] nbytes, int index, int count) { 184 grow(count - len); 185 int newSize = realSize + count - len; 186 System.arraycopy(bytes,beg+len,bytes,beg+count,realSize - (len+beg)); 187 System.arraycopy(nbytes,index,bytes,beg,count); 188 realSize = newSize; 189 } 190 191 public void replace(int beg, int len, ByteList nbytes) { 192 replace(beg, len, nbytes.bytes, 0, nbytes.realSize); 193 } 194 195 public void replace(int beg, int len, byte[] buf) { 196 replace(beg, len, buf, 0, buf.length); 197 } 198 199 public void replace(int beg, int len, byte[] nbytes, int index, int count) { 200 if (len - beg > realSize) throw new IndexOutOfBoundsException (); 201 unsafeReplace(beg,len,nbytes,index,count); 202 } 203 204 public void insert(int index, int b) { 205 if (index >= realSize) throw new IndexOutOfBoundsException (); 206 grow(1); 207 System.arraycopy(bytes,index,bytes,index+1,realSize-index); 208 bytes[index] = (byte)b; 209 realSize++; 210 } 211 212 public boolean equals(Object other) { 213 if (other == this) return true; 214 if (other instanceof ByteList) { 215 ByteList b = (ByteList) other; 216 if (b.realSize != realSize) { 217 return false; 218 } 219 for (int i = 0; i < realSize; i++) { 220 if (bytes[i] != b.bytes[i]) { 221 return false; 222 } 223 } 224 return true; 225 } 226 return false; 227 } 228 229 233 public int compareTo(Object other) { 234 return cmp((ByteList)other); 235 } 236 237 public int cmp(ByteList other) { 238 if (other == this || other.bytes == bytes) return 0; 239 int len = Math.min(realSize,other.realSize); 240 int retval = 0; 241 for(int i=0;i<len && retval == 0;i++) { 242 retval = (bytes[i]&0xFF) - (other.bytes[i]&0xFF); 243 } 244 if(retval == 0) { 245 if(realSize == other.realSize) { 246 return 0; 247 } else if(realSize > len) { 248 return 1; 249 } 250 return -1; 251 } 252 if(retval > 0) { 253 return 1; 254 } 255 return -1; 256 } 257 258 265 public byte[] unsafeBytes() { 266 return bytes; 267 } 268 269 public byte[] bytes() { 270 byte[] newBytes = new byte[realSize]; 271 System.arraycopy(bytes, 0, newBytes, 0, realSize); 272 return newBytes; 273 } 274 275 public Object clone() { 276 return new ByteList(bytes, 0, realSize); 277 } 278 279 private void grow(int increaseRequested) { 280 if (increaseRequested < 0) { 281 return; 282 } 283 int newSize = realSize + increaseRequested; 284 if (bytes.length < newSize) { 285 byte[] newBytes = new byte[(int) (newSize * FACTOR)]; 286 System.arraycopy(bytes,0,newBytes,0,realSize); 287 bytes = newBytes; 288 } 289 } 290 291 295 public int hashCode() { 296 int key = 0; 297 int g; 298 for(int i = 0; i < realSize; i++) { 299 key = (key << 4) + (((int)bytes[i]) & 0xFF); 300 if((g = key & 0xF0000000) != 0) { 301 key ^= g >> 24; 302 } 303 key &= ~g; 304 } 305 return key; 306 } 307 308 public String toString() { 309 return new String (this.bytes,0,realSize); 310 } 311 312 public static ByteList create(CharSequence s) { 313 return new ByteList(plain(s),false); 314 } 315 316 public static byte[] plain(CharSequence s) { 317 byte[] bytes = new byte[s.length()]; 318 for (int i = 0; i < bytes.length; i++) { 319 bytes[i] = (byte) s.charAt(i); 320 } 321 return bytes; 322 } 323 324 public static byte[] plain(char[] s) { 325 byte[] bytes = new byte[s.length]; 326 for (int i = 0; i < s.length; i++) { 327 bytes[i] = (byte) s[i]; 328 } 329 return bytes; 330 } 331 332 public static char[] plain(byte[] b) { 333 char[] chars = new char[b.length]; 334 for (int i = 0; i < b.length; i++) { 335 chars[i] = (char) (b[i] & 0xFF); 336 } 337 return chars; 338 } 339 340 public char charAt(int ix) { 341 return (char)(this.bytes[ix] & 0xFF); 342 } 343 344 public CharSequence subSequence(int start, int end) { 345 return new ByteList(this, start, end-start); 346 } 347 } 348 | Popular Tags |