1 package org.sapia.ubik.util; 2 3 import java.io.IOException ; 4 import java.io.OutputStream ; 5 import java.nio.ByteBuffer ; 6 7 46 public class ByteVector { 47 48 public static final int DEFAULT_ARRAY_CAPACITY = 200; 49 public static final int DEFAULT_INCREMENT = 10; 50 51 private int _arrayPos, _markPos, _markOffset, _arrayCount; 52 private int _capacity = DEFAULT_ARRAY_CAPACITY; 53 private int _increment = DEFAULT_INCREMENT; 54 55 private ByteArray[] _arrays = new ByteArray[_increment]; 56 57 60 public ByteVector(){} 61 62 71 public ByteVector(int capacity, int increment){ 72 _capacity = capacity; 73 _increment = increment; 74 } 75 76 77 85 public void mark(int mark){ 86 if(mark < _capacity){ 87 _markPos = 0; 88 _markOffset = mark; 89 } 90 else{ 91 int pos = mark/_capacity; 92 int offset = mark%_capacity; 93 if(pos >= _arrayCount){ 94 throw new IndexOutOfBoundsException (""+mark); 95 } 96 _markPos = pos; 97 _markOffset = offset; 98 } 99 } 100 101 107 public void reset(){ 108 _arrayPos = _markPos; 109 _arrays[_arrayPos]._pos = _markOffset; 110 for(int i = _arrayPos+1; i < _arrayCount; i++){ 111 _arrays[i]._pos = 0; 112 } 113 } 114 115 121 public void clear(boolean freeMemory){ 122 _arrayPos = 0; 123 _markOffset = 0; 124 _markPos = 0; 125 if(freeMemory){ 126 _arrays = new ByteArray[_increment]; 127 } 128 else{ 129 for(int i = 0; i < _arrayCount; i++){ 130 _arrays[i]._pos = 0; 131 _arrays[i]._limit = 0; 132 } 133 } 134 _arrayCount = 0; 135 } 136 137 140 public int length(){ 141 if(_arrayCount == 0){ 142 return 0; 143 } 144 return (_arrayCount-1)*_capacity+_arrays[_arrayCount-1]._limit; 145 } 146 147 151 public int position(){ 152 if(_arrayCount == 0){ 153 return 0; 154 } 155 else if(_arrayPos == 0){ 156 return _arrays[_arrayPos]._pos; 157 } 158 if(_arrayPos >= _arrayCount){ 159 return (_arrayCount-1) * _capacity + _arrays[_arrayCount-1]._pos; 160 } 161 else{ 162 return _arrayPos * _capacity + _arrays[_arrayPos]._pos; 163 } 164 } 165 166 171 public int remaining(){ 172 return length() - position(); 173 } 174 175 int arrayPosition(){ 176 return _arrayPos; 177 } 178 179 int arrayCount(){ 180 return _arrayCount; 181 } 182 183 187 public boolean hasRemaining(){ 188 return _arrayPos < _arrayCount && _arrays[_arrayPos]._pos < _arrays[_arrayPos]._limit; 189 } 190 191 195 public byte[] toByteArray(){ 196 if(_arrayCount == 0 || _arrays[0] == null){ 197 return new byte[0]; 198 } 199 byte[] b = new byte[length()]; 200 int index = 0; 201 for(int i = _arrayPos; i < _arrayCount; i++){ 202 for(int j = 0; j < _arrays[i]._limit; j++){ 203 b[index] = _arrays[i]._bytes[j]; 204 index++; 205 } 206 } 207 return b; 208 } 209 210 214 public int read(){ 215 if(_arrayCount == 0 || _arrayPos >= _arrayCount){ 216 return -1; 217 } 218 ByteArray arr = _arrays[_arrayPos]; 219 if(arr == null) return -1; 220 if(arr._pos < arr._limit){ 221 int b = arr._bytes[arr._pos++] & 0xff; 222 if(arr._pos >= arr._limit){ 223 _arrayPos++; 224 } 225 return b; 226 } 227 return -1; 228 } 229 230 235 public int read(byte[] b){ 236 return read(b, 0, b.length); 237 } 238 239 246 public int read(byte[] b, int off, int len){ 247 int read = 0; 248 int total = 0; 249 while(len > 0 && _arrayPos < _arrayCount){ 250 read = _arrays[_arrayPos].get(b, off, len); 251 if(read == 0){ 252 break; 253 } 254 if(_arrays[_arrayPos]._pos >= _arrays[_arrayPos]._limit){ 255 _arrayPos++; 256 } 257 len = len - read; 258 off = off + read; 259 total += read; 260 } 261 return total; 262 } 263 264 268 public int read(ByteBuffer buf){ 269 int read = 0; 270 int total = 0; 271 int len = buf.remaining(); 272 while(len > 0 && _arrayPos < _arrayCount){ 273 read = _arrays[_arrayPos].get(buf, len); 274 if(read == 0){ 275 break; 276 } 277 if(_arrays[_arrayPos]._pos >= _arrays[_arrayPos]._limit){ 278 _arrayPos++; 279 } 280 len = len - read; 281 total += read; 282 } 283 return total; 284 285 } 286 287 292 public void read(OutputStream out) throws IOException { 293 int read; 294 while(_arrayPos < _arrayCount){ 295 read = _arrays[_arrayPos].get(out); 296 if(read == 0){ 297 break; 298 } 299 if(_arrays[_arrayPos]._pos >= _arrays[_arrayPos]._limit){ 300 _arrayPos++; 301 } 302 } 303 } 304 305 310 public void write(byte[] b){ 311 write(b, 0, b.length); 312 } 313 314 public void write(int b){ 315 if(_arrayPos >= _arrayCount) 316 increase(); 317 if(!_arrays[_arrayPos++].put((byte)b)){ 318 increase(); 319 _arrays[_arrayPos-1].put((byte)b); 320 } 321 } 322 323 331 public void write(byte[] b, int off, int len){ 332 int put = 0; 333 while(put < len){ 334 if(_arrayPos >= _arrayCount){ 335 increase(); 336 } 337 put = _arrays[_arrayPos].put(b, off, len); 338 if(put < len){ 339 _arrayPos++; 340 } 341 off += put; 342 len -= put; 343 put = 0; 344 } 345 } 346 347 352 public void write(ByteBuffer buf){ 353 while(buf.hasRemaining()){ 354 if(_arrayPos >= _arrayCount){ 355 increase(); 356 } 357 int len = buf.remaining(); 358 int put = _arrays[_arrayPos].put(buf); 359 if(put < len){ 360 _arrayPos++; 361 } 362 put = 0; 363 } 364 } 365 366 371 public long skip(long skip){ 372 if(_arrayCount == 0){ 373 return 0; 374 } 375 long total = 0; 376 while(total < skip && _arrayPos < _arrayCount){ 377 ByteArray arr = _arrays[_arrayPos]; 378 379 if(arr == null) 380 break; 381 382 int size = arr._limit - arr._pos; 383 384 if(size <= 0) 385 break; 386 387 if(total + size <= skip){ 388 arr._pos = arr._limit; 389 total = total + size; 390 _arrayPos++; 391 } 392 else{ 393 size = (int)(skip - total); 394 arr._pos = arr._pos + size; 395 total = total + size; 396 } 397 } 398 return total; 399 } 400 401 private void increase(){ 402 if(_arrayPos >= _arrays.length){ 403 ByteArray[] newArray = new ByteArray[_arrays.length+_increment]; 404 System.arraycopy(_arrays, 0, newArray, 0, _arrays.length); 405 _arrays = newArray; 406 } 407 if(_arrays[_arrayPos] == null){ 408 _arrays[_arrayPos] = new ByteArray(_capacity); 409 } 410 _arrayCount++; 411 } 412 413 415 static class ByteArray{ 416 int _pos; 417 int _limit; 418 byte[] _bytes; 419 ByteArray(int capacity){ 420 _bytes = new byte[capacity]; 421 } 422 423 boolean put(byte b){ 424 if(_pos < _bytes.length){ 425 _bytes[_pos++] = b; 426 _limit++; 427 } 428 return false; 429 } 430 431 int put(byte[] b, int offset, int len){ 432 if(_pos < _bytes.length){ 433 if(len <= _bytes.length - _pos){ 434 System.arraycopy(b, offset, _bytes, _pos, len); 435 _pos += len; 436 _limit += len; 437 return len; 438 } 439 else{ 440 System.arraycopy(b, offset, _bytes, _pos, _bytes.length - _pos); 441 int put = _bytes.length - _pos; 442 _pos += put; 443 _limit += put; 444 return put; 445 } 446 } 447 return 0; 448 } 449 450 int put(ByteBuffer buf){ 451 if(_pos < _bytes.length){ 452 if(buf.remaining() <= _bytes.length - _pos){ 453 int len = buf.remaining(); 454 buf.get(_bytes, _pos, buf.remaining()); 455 _pos += len; 456 _limit += len; 457 return len; 458 } 459 else{ 460 buf.get(_bytes, _pos, _bytes.length - _pos); 461 int put = _bytes.length - _pos; 462 _pos += put; 463 _limit += put; 464 return put; 465 } 466 } 467 return 0; 468 } 469 470 int get(byte[] b, int offset, int len){ 471 if(_pos < _limit){ 472 if(_limit - _pos <= len){ 473 System.arraycopy(_bytes, _pos, b, offset, _limit - _pos); 474 int read = _limit - _pos; 475 _pos += read; 476 return read; 477 } 478 else{ 479 System.arraycopy(_bytes, _pos, b, offset, len); 480 _pos += len; 481 return len; 482 } 483 } 484 return 0; 485 } 486 487 int get(ByteBuffer buf, int len){ 488 if(_pos < _limit){ 489 if(_limit - _pos <= len){ 490 buf.put(_bytes, _pos, _limit - _pos); 491 int read = _limit - _pos; 492 _pos += read; 493 return read; 494 } 495 else{ 496 buf.put(_bytes, _pos, len); 497 _pos += len; 498 return len; 499 } 500 } 501 return 0; 502 } 503 504 int get(OutputStream out) throws IOException { 505 if(_pos >= _limit){ 506 return 0; 507 } 508 out.write(_bytes, _pos, _limit); 509 int read = _limit - _pos; 510 _pos = _pos + read; 511 return read; 512 } 513 } 514 515 } 516 | Popular Tags |