1 18 19 23 24 package org.apache.tools.tar; 25 26 import java.io.InputStream ; 27 import java.io.OutputStream ; 28 import java.io.IOException ; 29 import java.util.Arrays ; 30 31 43 44 public class TarBuffer { 45 46 47 public static final int DEFAULT_RCDSIZE = (512); 48 49 50 public static final int DEFAULT_BLKSIZE = (DEFAULT_RCDSIZE * 20); 51 52 private InputStream inStream; 53 private OutputStream outStream; 54 private byte[] blockBuffer; 55 private int currBlkIdx; 56 private int currRecIdx; 57 private int blockSize; 58 private int recordSize; 59 private int recsPerBlock; 60 private boolean debug; 61 62 66 public TarBuffer(InputStream inStream) { 67 this(inStream, TarBuffer.DEFAULT_BLKSIZE); 68 } 69 70 75 public TarBuffer(InputStream inStream, int blockSize) { 76 this(inStream, blockSize, TarBuffer.DEFAULT_RCDSIZE); 77 } 78 79 85 public TarBuffer(InputStream inStream, int blockSize, int recordSize) { 86 this.inStream = inStream; 87 this.outStream = null; 88 89 this.initialize(blockSize, recordSize); 90 } 91 92 96 public TarBuffer(OutputStream outStream) { 97 this(outStream, TarBuffer.DEFAULT_BLKSIZE); 98 } 99 100 105 public TarBuffer(OutputStream outStream, int blockSize) { 106 this(outStream, blockSize, TarBuffer.DEFAULT_RCDSIZE); 107 } 108 109 115 public TarBuffer(OutputStream outStream, int blockSize, int recordSize) { 116 this.inStream = null; 117 this.outStream = outStream; 118 119 this.initialize(blockSize, recordSize); 120 } 121 122 125 private void initialize(int blockSize, int recordSize) { 126 this.debug = false; 127 this.blockSize = blockSize; 128 this.recordSize = recordSize; 129 this.recsPerBlock = (this.blockSize / this.recordSize); 130 this.blockBuffer = new byte[this.blockSize]; 131 132 if (this.inStream != null) { 133 this.currBlkIdx = -1; 134 this.currRecIdx = this.recsPerBlock; 135 } else { 136 this.currBlkIdx = 0; 137 this.currRecIdx = 0; 138 } 139 } 140 141 145 public int getBlockSize() { 146 return this.blockSize; 147 } 148 149 153 public int getRecordSize() { 154 return this.recordSize; 155 } 156 157 162 public void setDebug(boolean debug) { 163 this.debug = debug; 164 } 165 166 173 public boolean isEOFRecord(byte[] record) { 174 for (int i = 0, sz = this.getRecordSize(); i < sz; ++i) { 175 if (record[i] != 0) { 176 return false; 177 } 178 } 179 180 return true; 181 } 182 183 187 public void skipRecord() throws IOException { 188 if (this.debug) { 189 System.err.println("SkipRecord: recIdx = " + this.currRecIdx 190 + " blkIdx = " + this.currBlkIdx); 191 } 192 193 if (this.inStream == null) { 194 throw new IOException ("reading (via skip) from an output buffer"); 195 } 196 197 if (this.currRecIdx >= this.recsPerBlock) { 198 if (!this.readBlock()) { 199 return; } 201 } 202 203 this.currRecIdx++; 204 } 205 206 212 public byte[] readRecord() throws IOException { 213 if (this.debug) { 214 System.err.println("ReadRecord: recIdx = " + this.currRecIdx 215 + " blkIdx = " + this.currBlkIdx); 216 } 217 218 if (this.inStream == null) { 219 throw new IOException ("reading from an output buffer"); 220 } 221 222 if (this.currRecIdx >= this.recsPerBlock) { 223 if (!this.readBlock()) { 224 return null; 225 } 226 } 227 228 byte[] result = new byte[this.recordSize]; 229 230 System.arraycopy(this.blockBuffer, 231 (this.currRecIdx * this.recordSize), result, 0, 232 this.recordSize); 233 234 this.currRecIdx++; 235 236 return result; 237 } 238 239 242 private boolean readBlock() throws IOException { 243 if (this.debug) { 244 System.err.println("ReadBlock: blkIdx = " + this.currBlkIdx); 245 } 246 247 if (this.inStream == null) { 248 throw new IOException ("reading from an output buffer"); 249 } 250 251 this.currRecIdx = 0; 252 253 int offset = 0; 254 int bytesNeeded = this.blockSize; 255 256 while (bytesNeeded > 0) { 257 long numBytes = this.inStream.read(this.blockBuffer, offset, 258 bytesNeeded); 259 260 if (numBytes == -1) { 274 if (offset == 0) { 275 return false; 279 } 280 286 Arrays.fill(blockBuffer, offset, offset + bytesNeeded, (byte) 0); 287 288 break; 289 } 290 291 offset += numBytes; 292 bytesNeeded -= numBytes; 293 294 if (numBytes != this.blockSize) { 295 if (this.debug) { 296 System.err.println("ReadBlock: INCOMPLETE READ " 297 + numBytes + " of " + this.blockSize 298 + " bytes read."); 299 } 300 } 301 } 302 303 this.currBlkIdx++; 304 305 return true; 306 } 307 308 313 public int getCurrentBlockNum() { 314 return this.currBlkIdx; 315 } 316 317 323 public int getCurrentRecordNum() { 324 return this.currRecIdx - 1; 325 } 326 327 333 public void writeRecord(byte[] record) throws IOException { 334 if (this.debug) { 335 System.err.println("WriteRecord: recIdx = " + this.currRecIdx 336 + " blkIdx = " + this.currBlkIdx); 337 } 338 339 if (this.outStream == null) { 340 throw new IOException ("writing to an input buffer"); 341 } 342 343 if (record.length != this.recordSize) { 344 throw new IOException ("record to write has length '" 345 + record.length 346 + "' which is not the record size of '" 347 + this.recordSize + "'"); 348 } 349 350 if (this.currRecIdx >= this.recsPerBlock) { 351 this.writeBlock(); 352 } 353 354 System.arraycopy(record, 0, this.blockBuffer, 355 (this.currRecIdx * this.recordSize), 356 this.recordSize); 357 358 this.currRecIdx++; 359 } 360 361 370 public void writeRecord(byte[] buf, int offset) throws IOException { 371 if (this.debug) { 372 System.err.println("WriteRecord: recIdx = " + this.currRecIdx 373 + " blkIdx = " + this.currBlkIdx); 374 } 375 376 if (this.outStream == null) { 377 throw new IOException ("writing to an input buffer"); 378 } 379 380 if ((offset + this.recordSize) > buf.length) { 381 throw new IOException ("record has length '" + buf.length 382 + "' with offset '" + offset 383 + "' which is less than the record size of '" 384 + this.recordSize + "'"); 385 } 386 387 if (this.currRecIdx >= this.recsPerBlock) { 388 this.writeBlock(); 389 } 390 391 System.arraycopy(buf, offset, this.blockBuffer, 392 (this.currRecIdx * this.recordSize), 393 this.recordSize); 394 395 this.currRecIdx++; 396 } 397 398 401 private void writeBlock() throws IOException { 402 if (this.debug) { 403 System.err.println("WriteBlock: blkIdx = " + this.currBlkIdx); 404 } 405 406 if (this.outStream == null) { 407 throw new IOException ("writing to an input buffer"); 408 } 409 410 this.outStream.write(this.blockBuffer, 0, this.blockSize); 411 this.outStream.flush(); 412 413 this.currRecIdx = 0; 414 this.currBlkIdx++; 415 } 416 417 420 private void flushBlock() throws IOException { 421 if (this.debug) { 422 System.err.println("TarBuffer.flushBlock() called."); 423 } 424 425 if (this.outStream == null) { 426 throw new IOException ("writing to an input buffer"); 427 } 428 429 if (this.currRecIdx > 0) { 430 this.writeBlock(); 431 } 432 } 433 434 439 public void close() throws IOException { 440 if (this.debug) { 441 System.err.println("TarBuffer.closeBuffer()."); 442 } 443 444 if (this.outStream != null) { 445 this.flushBlock(); 446 447 if (this.outStream != System.out 448 && this.outStream != System.err) { 449 this.outStream.close(); 450 451 this.outStream = null; 452 } 453 } else if (this.inStream != null) { 454 if (this.inStream != System.in) { 455 this.inStream.close(); 456 457 this.inStream = null; 458 } 459 } 460 } 461 } 462 | Popular Tags |