git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274796 13f79535-47bb-0310-9956-ffa450edef68master
@@ -29,7 +29,7 @@ | |||
<formatter type="xml" toFile="${checkstyle.raw}"/> | |||
<fileset dir="${java.dir}"> | |||
<include name="${tocheck}"/> | |||
<exclude name="**/BZip2Constants.java"/> | |||
<exclude name="**/bzip2/*.java"/> | |||
<exclude name="**/CVSPass.java"/> | |||
</fileset> | |||
</checkstyle> | |||
@@ -139,12 +139,12 @@ public class CBZip2InputStream extends InputStream implements BZip2Constants { | |||
freq table collected to save a pass over the data | |||
during decompression. | |||
*/ | |||
private int unzftab[] = new int[256]; | |||
private int[] unzftab = new int[256]; | |||
private int limit[][] = new int[N_GROUPS][MAX_ALPHA_SIZE]; | |||
private int base[][] = new int[N_GROUPS][MAX_ALPHA_SIZE]; | |||
private int perm[][] = new int[N_GROUPS][MAX_ALPHA_SIZE]; | |||
private int minLens[] = new int[N_GROUPS]; | |||
private int[][] limit = new int[N_GROUPS][MAX_ALPHA_SIZE]; | |||
private int[][] base = new int[N_GROUPS][MAX_ALPHA_SIZE]; | |||
private int[][] perm = new int[N_GROUPS][MAX_ALPHA_SIZE]; | |||
private int[] minLens = new int[N_GROUPS]; | |||
private InputStream bsStream; | |||
@@ -302,10 +302,11 @@ public class CBZip2InputStream extends InputStream implements BZip2Constants { | |||
if (this.bsStream != null) { | |||
if (this.bsStream != System.in) { | |||
this.bsStream.close(); | |||
this.bsStream= null; | |||
this.bsStream = null; | |||
} | |||
} | |||
} catch (IOException ioe) { | |||
//ignore | |||
} | |||
} | |||
@@ -319,22 +320,20 @@ public class CBZip2InputStream extends InputStream implements BZip2Constants { | |||
private int bsR(int n) { | |||
int v; | |||
{ | |||
while (bsLive < n) { | |||
int zzi; | |||
char thech = 0; | |||
try { | |||
thech = (char) bsStream.read(); | |||
} catch (IOException e) { | |||
compressedStreamEOF(); | |||
} | |||
if (thech == -1) { | |||
compressedStreamEOF(); | |||
} | |||
zzi = thech; | |||
bsBuff = (bsBuff << 8) | (zzi & 0xff); | |||
bsLive += 8; | |||
while (bsLive < n) { | |||
int zzi; | |||
char thech = 0; | |||
try { | |||
thech = (char) bsStream.read(); | |||
} catch (IOException e) { | |||
compressedStreamEOF(); | |||
} | |||
if (thech == -1) { | |||
compressedStreamEOF(); | |||
} | |||
zzi = thech; | |||
bsBuff = (bsBuff << 8) | (zzi & 0xff); | |||
bsLive += 8; | |||
} | |||
v = (bsBuff >> (bsLive - n)) & ((1 << n) - 1); | |||
@@ -376,7 +375,7 @@ public class CBZip2InputStream extends InputStream implements BZip2Constants { | |||
pp++; | |||
} | |||
} | |||
}; | |||
} | |||
for (i = 0; i < MAX_CODE_LEN; i++) { | |||
base[i] = 0; | |||
@@ -618,7 +617,7 @@ public class CBZip2InputStream extends InputStream implements BZip2Constants { | |||
bsLive--; | |||
} | |||
zvec = (zvec << 1) | zj; | |||
}; | |||
} | |||
nextSym = perm[zt][zvec - base[zt][zn]]; | |||
} | |||
} while (nextSym == RUNA || nextSym == RUNB); | |||
@@ -631,7 +630,7 @@ public class CBZip2InputStream extends InputStream implements BZip2Constants { | |||
last++; | |||
ll8[last] = ch; | |||
s--; | |||
}; | |||
} | |||
if (last >= limitLast) { | |||
blockOverrun(); | |||
@@ -698,7 +697,7 @@ public class CBZip2InputStream extends InputStream implements BZip2Constants { | |||
bsLive--; | |||
} | |||
zvec = (zvec << 1) | zj; | |||
}; | |||
} | |||
nextSym = perm[zt][zvec - base[zt][zn]]; | |||
} | |||
continue; | |||
@@ -163,8 +163,8 @@ public class CBZip2OutputStream extends OutputStream implements BZip2Constants { | |||
if (yy > nHeap) { | |||
break; | |||
} | |||
if (yy < nHeap && | |||
weight[heap[yy + 1]] < weight[heap[yy]]) { | |||
if (yy < nHeap | |||
&& weight[heap[yy + 1]] < weight[heap[yy]]) { | |||
yy++; | |||
} | |||
if (weight[tmp] < weight[heap[yy]]) { | |||
@@ -187,8 +187,8 @@ public class CBZip2OutputStream extends OutputStream implements BZip2Constants { | |||
if (yy > nHeap) { | |||
break; | |||
} | |||
if (yy < nHeap && | |||
weight[heap[yy + 1]] < weight[heap[yy]]) { | |||
if (yy < nHeap | |||
&& weight[heap[yy + 1]] < weight[heap[yy]]) { | |||
yy++; | |||
} | |||
if (weight[tmp] < weight[heap[yy]]) { | |||
@@ -53,10 +53,10 @@ | |||
*/ | |||
/* | |||
* This package is based on the work done by Timothy Gerard Endres | |||
* This package is based on the work done by Timothy Gerard Endres | |||
* (time@ice.com) to whom the Ant project is very grateful for his great code. | |||
*/ | |||
package org.apache.tools.tar; | |||
import java.io.InputStream; | |||
@@ -73,15 +73,15 @@ import java.io.IOException; | |||
* <p> | |||
* You should never have a need to access this class directly. | |||
* TarBuffers are created by Tar IO Streams. | |||
* | |||
* | |||
* @author Timothy Gerard Endres <a href="mailto:time@ice.com">time@ice.com</a> | |||
*/ | |||
public class TarBuffer { | |||
public static final int DEFAULT_RCDSIZE = (512); | |||
public static final int DEFAULT_BLKSIZE = (DEFAULT_RCDSIZE * 20); | |||
private InputStream inStream; | |||
private OutputStream outStream; | |||
private byte[] blockBuffer; | |||
@@ -138,101 +138,101 @@ public class TarBuffer { | |||
} else { | |||
this.currBlkIdx = 0; | |||
this.currRecIdx = 0; | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* Get the TAR Buffer's block size. Blocks consist of multiple records. | |||
*/ | |||
public int getBlockSize() { | |||
return this.blockSize; | |||
} | |||
} | |||
/** | |||
* Get the TAR Buffer's record size. | |||
*/ | |||
public int getRecordSize() { | |||
return this.recordSize; | |||
} | |||
} | |||
/** | |||
* Set the debugging flag for the buffer. | |||
* | |||
* | |||
* @param debug If true, print debugging output. | |||
*/ | |||
public void setDebug(boolean debug) { | |||
this.debug = debug; | |||
} | |||
} | |||
/** | |||
* Determine if an archive record indicate End of Archive. End of | |||
* archive is indicated by a record that consists entirely of null bytes. | |||
* | |||
* | |||
* @param record The record data to check. | |||
*/ | |||
public boolean isEOFRecord(byte[] record) { | |||
for (int i = 0, sz = this.getRecordSize(); i < sz; ++i) { | |||
if (record[i] != 0) { | |||
return false; | |||
} | |||
} | |||
} | |||
return true; | |||
} | |||
} | |||
/** | |||
* Skip over a record on the input stream. | |||
*/ | |||
public void skipRecord() throws IOException { | |||
if (this.debug) { | |||
System.err.println("SkipRecord: recIdx = " + this.currRecIdx | |||
System.err.println("SkipRecord: recIdx = " + this.currRecIdx | |||
+ " blkIdx = " + this.currBlkIdx); | |||
} | |||
} | |||
if (this.inStream == null) { | |||
throw new IOException("reading (via skip) from an output buffer"); | |||
} | |||
} | |||
if (this.currRecIdx >= this.recsPerBlock) { | |||
if (!this.readBlock()) { | |||
return; // UNDONE | |||
} | |||
} | |||
} | |||
} | |||
this.currRecIdx++; | |||
} | |||
} | |||
/** | |||
* Read a record from the input stream and return the data. | |||
* | |||
* | |||
* @return The record data. | |||
*/ | |||
public byte[] readRecord() throws IOException { | |||
if (this.debug) { | |||
System.err.println("ReadRecord: recIdx = " + this.currRecIdx | |||
System.err.println("ReadRecord: recIdx = " + this.currRecIdx | |||
+ " blkIdx = " + this.currBlkIdx); | |||
} | |||
} | |||
if (this.inStream == null) { | |||
throw new IOException("reading from an output buffer"); | |||
} | |||
} | |||
if (this.currRecIdx >= this.recsPerBlock) { | |||
if (!this.readBlock()) { | |||
return null; | |||
} | |||
} | |||
} | |||
} | |||
byte[] result = new byte[this.recordSize]; | |||
System.arraycopy(this.blockBuffer, | |||
(this.currRecIdx * this.recordSize), result, 0, | |||
System.arraycopy(this.blockBuffer, | |||
(this.currRecIdx * this.recordSize), result, 0, | |||
this.recordSize); | |||
this.currRecIdx++; | |||
return result; | |||
} | |||
} | |||
/** | |||
* @return false if End-Of-File, else true | |||
@@ -240,11 +240,11 @@ public class TarBuffer { | |||
private boolean readBlock() throws IOException { | |||
if (this.debug) { | |||
System.err.println("ReadBlock: blkIdx = " + this.currBlkIdx); | |||
} | |||
} | |||
if (this.inStream == null) { | |||
throw new IOException("reading from an output buffer"); | |||
} | |||
} | |||
this.currRecIdx = 0; | |||
@@ -252,130 +252,130 @@ public class TarBuffer { | |||
int bytesNeeded = this.blockSize; | |||
while (bytesNeeded > 0) { | |||
long numBytes = this.inStream.read(this.blockBuffer, offset, | |||
long numBytes = this.inStream.read(this.blockBuffer, offset, | |||
bytesNeeded); | |||
// | |||
// | |||
// NOTE | |||
// We have fit EOF, and the block is not full! | |||
// | |||
// | |||
// This is a broken archive. It does not follow the standard | |||
// blocking algorithm. However, because we are generous, and | |||
// it requires little effort, we will simply ignore the error | |||
// and continue as if the entire block were read. This does | |||
// not appear to break anything upstream. We used to return | |||
// false in this case. | |||
// | |||
// | |||
// Thanks to 'Yohann.Roussel@alcatel.fr' for this fix. | |||
// | |||
// | |||
if (numBytes == -1) { | |||
break; | |||
} | |||
} | |||
offset += numBytes; | |||
bytesNeeded -= numBytes; | |||
if (numBytes != this.blockSize) { | |||
if (this.debug) { | |||
System.err.println("ReadBlock: INCOMPLETE READ " | |||
+ numBytes + " of " + this.blockSize | |||
System.err.println("ReadBlock: INCOMPLETE READ " | |||
+ numBytes + " of " + this.blockSize | |||
+ " bytes read."); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
this.currBlkIdx++; | |||
return true; | |||
} | |||
} | |||
/** | |||
* Get the current block number, zero based. | |||
* | |||
* | |||
* @return The current zero based block number. | |||
*/ | |||
public int getCurrentBlockNum() { | |||
return this.currBlkIdx; | |||
} | |||
} | |||
/** | |||
* Get the current record number, within the current block, zero based. | |||
* Thus, current offset = (currentBlockNum * recsPerBlk) + currentRecNum. | |||
* | |||
* | |||
* @return The current zero based record number. | |||
*/ | |||
public int getCurrentRecordNum() { | |||
return this.currRecIdx - 1; | |||
} | |||
} | |||
/** | |||
* Write an archive record to the archive. | |||
* | |||
* | |||
* @param record The record data to write to the archive. | |||
*/ | |||
public void writeRecord(byte[] record) throws IOException { | |||
if (this.debug) { | |||
System.err.println("WriteRecord: recIdx = " + this.currRecIdx | |||
System.err.println("WriteRecord: recIdx = " + this.currRecIdx | |||
+ " blkIdx = " + this.currBlkIdx); | |||
} | |||
} | |||
if (this.outStream == null) { | |||
throw new IOException("writing to an input buffer"); | |||
} | |||
} | |||
if (record.length != this.recordSize) { | |||
throw new IOException("record to write has length '" | |||
+ record.length | |||
+ "' which is not the record size of '" | |||
throw new IOException("record to write has length '" | |||
+ record.length | |||
+ "' which is not the record size of '" | |||
+ this.recordSize + "'"); | |||
} | |||
} | |||
if (this.currRecIdx >= this.recsPerBlock) { | |||
this.writeBlock(); | |||
} | |||
} | |||
System.arraycopy(record, 0, this.blockBuffer, | |||
(this.currRecIdx * this.recordSize), | |||
System.arraycopy(record, 0, this.blockBuffer, | |||
(this.currRecIdx * this.recordSize), | |||
this.recordSize); | |||
this.currRecIdx++; | |||
} | |||
} | |||
/** | |||
* Write an archive record to the archive, where the record may be | |||
* inside of a larger array buffer. The buffer must be "offset plus | |||
* record size" long. | |||
* | |||
* | |||
* @param buf The buffer containing the record data to write. | |||
* @param offset The offset of the record data within buf. | |||
*/ | |||
public void writeRecord(byte[] buf, int offset) throws IOException { | |||
if (this.debug) { | |||
System.err.println("WriteRecord: recIdx = " + this.currRecIdx | |||
System.err.println("WriteRecord: recIdx = " + this.currRecIdx | |||
+ " blkIdx = " + this.currBlkIdx); | |||
} | |||
} | |||
if (this.outStream == null) { | |||
throw new IOException("writing to an input buffer"); | |||
} | |||
} | |||
if ((offset + this.recordSize) > buf.length) { | |||
throw new IOException("record has length '" + buf.length | |||
+ "' with offset '" + offset | |||
+ "' which is less than the record size of '" | |||
throw new IOException("record has length '" + buf.length | |||
+ "' with offset '" + offset | |||
+ "' which is less than the record size of '" | |||
+ this.recordSize + "'"); | |||
} | |||
} | |||
if (this.currRecIdx >= this.recsPerBlock) { | |||
this.writeBlock(); | |||
} | |||
} | |||
System.arraycopy(buf, offset, this.blockBuffer, | |||
(this.currRecIdx * this.recordSize), | |||
System.arraycopy(buf, offset, this.blockBuffer, | |||
(this.currRecIdx * this.recordSize), | |||
this.recordSize); | |||
this.currRecIdx++; | |||
} | |||
} | |||
/** | |||
* Write a TarBuffer block to the archive. | |||
@@ -383,18 +383,18 @@ public class TarBuffer { | |||
private void writeBlock() throws IOException { | |||
if (this.debug) { | |||
System.err.println("WriteBlock: blkIdx = " + this.currBlkIdx); | |||
} | |||
} | |||
if (this.outStream == null) { | |||
throw new IOException("writing to an input buffer"); | |||
} | |||
} | |||
this.outStream.write(this.blockBuffer, 0, this.blockSize); | |||
this.outStream.flush(); | |||
this.currRecIdx = 0; | |||
this.currBlkIdx++; | |||
} | |||
} | |||
/** | |||
* Flush the current data block if it has any data in it. | |||
@@ -402,16 +402,16 @@ public class TarBuffer { | |||
private void flushBlock() throws IOException { | |||
if (this.debug) { | |||
System.err.println("TarBuffer.flushBlock() called."); | |||
} | |||
} | |||
if (this.outStream == null) { | |||
throw new IOException("writing to an input buffer"); | |||
} | |||
} | |||
if (this.currRecIdx > 0) { | |||
this.writeBlock(); | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* Close the TarBuffer. If this is an output buffer, also flush the | |||
@@ -420,23 +420,23 @@ public class TarBuffer { | |||
public void close() throws IOException { | |||
if (this.debug) { | |||
System.err.println("TarBuffer.closeBuffer()."); | |||
} | |||
} | |||
if (this.outStream != null) { | |||
this.flushBlock(); | |||
if (this.outStream != System.out | |||
if (this.outStream != System.out | |||
&& this.outStream != System.err) { | |||
this.outStream.close(); | |||
this.outStream = null; | |||
} | |||
} | |||
} else if (this.inStream != null) { | |||
if (this.inStream != System.in) { | |||
this.inStream.close(); | |||
this.inStream = null; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -1,7 +1,7 @@ | |||
/* | |||
* The Apache Software License, Version 1.1 | |||
* | |||
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights | |||
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights | |||
* reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or without | |||
@@ -53,7 +53,7 @@ | |||
*/ | |||
/* | |||
* This package is based on the work done by Timothy Gerard Endres | |||
* This package is based on the work done by Timothy Gerard Endres | |||
* (time@ice.com) to whom the Ant project is very grateful for his great code. | |||
*/ | |||
@@ -67,7 +67,7 @@ package org.apache.tools.tar; | |||
*/ | |||
public interface TarConstants { | |||
/** | |||
* The length of the name field in a header buffer. | |||
*/ | |||
@@ -183,9 +183,9 @@ public interface TarConstants { | |||
* The namr of the GNU tar entry which contains a long name. | |||
*/ | |||
String GNU_LONGLINK = "././@LongLink"; | |||
/** | |||
* Identifies the *next* file on the tape as having a long name. | |||
* Identifies the *next* file on the tape as having a long name. | |||
*/ | |||
byte LF_GNUTYPE_LONGNAME = (byte) 'L'; | |||
} |
@@ -84,7 +84,7 @@ public class TarInputStream extends FilterInputStream { | |||
protected TarBuffer buffer; | |||
protected TarEntry currEntry; | |||
private boolean v7Format; | |||
public TarInputStream(InputStream is) { | |||
this(is, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE); | |||
} | |||
@@ -53,7 +53,7 @@ | |||
*/ | |||
/* | |||
* This package is based on the work done by Timothy Gerard Endres | |||
* This package is based on the work done by Timothy Gerard Endres | |||
* (time@ice.com) to whom the Ant project is very grateful for his great code. | |||
*/ | |||
@@ -67,19 +67,19 @@ import java.io.IOException; | |||
* The TarOutputStream writes a UNIX tar archive as an OutputStream. | |||
* Methods are provided to put entries, and then write their contents | |||
* by writing to this stream using write(). | |||
* | |||
* | |||
* @author Timothy Gerard Endres <a href="mailto:time@ice.com">time@ice.com</a> | |||
*/ | |||
public class TarOutputStream extends FilterOutputStream { | |||
/** Fail if a long file name is required in the archive. */ | |||
public static final int LONGFILE_ERROR = 0; | |||
/** Long paths will be truncated in the archive. */ | |||
public static final int LONGFILE_TRUNCATE = 1; | |||
/** GNU tar extensions are used to store long file names in the archive. */ | |||
public static final int LONGFILE_GNU = 2; | |||
protected boolean debug; | |||
protected int currSize; | |||
protected int currBytes; | |||
@@ -112,25 +112,25 @@ public class TarOutputStream extends FilterOutputStream { | |||
public void setLongFileMode(int longFileMode) { | |||
this.longFileMode = longFileMode; | |||
} | |||
/** | |||
* Sets the debugging flag. | |||
* | |||
* | |||
* @param debugF True to turn on debugging. | |||
*/ | |||
public void setDebug(boolean debugF) { | |||
this.debug = debugF; | |||
} | |||
} | |||
/** | |||
* Sets the debugging flag in this stream's TarBuffer. | |||
* | |||
* | |||
* @param debugF True to turn on debugging. | |||
*/ | |||
public void setBufferDebug(boolean debug) { | |||
this.buffer.setDebug(debug); | |||
} | |||
} | |||
/** | |||
* Ends the TAR archive without closing the underlying OutputStream. | |||
@@ -138,7 +138,7 @@ public class TarOutputStream extends FilterOutputStream { | |||
*/ | |||
public void finish() throws IOException { | |||
this.writeEOFRecord(); | |||
} | |||
} | |||
/** | |||
* Ends the TAR archive and closes the underlying OutputStream. | |||
@@ -148,16 +148,16 @@ public class TarOutputStream extends FilterOutputStream { | |||
public void close() throws IOException { | |||
this.finish(); | |||
this.buffer.close(); | |||
} | |||
} | |||
/** | |||
* Get the record size being used by this stream's TarBuffer. | |||
* | |||
* | |||
* @return The TarBuffer record size. | |||
*/ | |||
public int getRecordSize() { | |||
return this.buffer.getRecordSize(); | |||
} | |||
} | |||
/** | |||
* Put an entry on the output stream. This writes the entry's | |||
@@ -167,7 +167,7 @@ public class TarOutputStream extends FilterOutputStream { | |||
* contents. Once the contents are written, closeEntry() | |||
* <B>MUST</B> be called to ensure that all buffered data | |||
* is completely written to the output stream. | |||
* | |||
* | |||
* @param entry The TarEntry to be written to the archive. | |||
*/ | |||
public void putNextEntry(TarEntry entry) throws IOException { | |||
@@ -175,21 +175,21 @@ public class TarOutputStream extends FilterOutputStream { | |||
if (longFileMode == LONGFILE_GNU) { | |||
// create a TarEntry for the LongLink, the contents | |||
// of which are the entry's name | |||
// of which are the entry's name | |||
TarEntry longLinkEntry = new TarEntry(TarConstants.GNU_LONGLINK, | |||
TarConstants.LF_GNUTYPE_LONGNAME); | |||
longLinkEntry.setSize(entry.getName().length() + 1); | |||
putNextEntry(longLinkEntry); | |||
putNextEntry(longLinkEntry); | |||
write(entry.getName().getBytes()); | |||
write(0); | |||
closeEntry(); | |||
} else if (longFileMode != LONGFILE_TRUNCATE) { | |||
throw new RuntimeException("file name '" + entry.getName() | |||
+ "' is too long ( > " | |||
throw new RuntimeException("file name '" + entry.getName() | |||
+ "' is too long ( > " | |||
+ TarConstants.NAMELEN + " bytes)"); | |||
} | |||
} | |||
} | |||
entry.writeEntryHeader(this.recordBuf); | |||
this.buffer.writeRecord(this.recordBuf); | |||
@@ -201,7 +201,7 @@ public class TarOutputStream extends FilterOutputStream { | |||
} else { | |||
this.currSize = (int) entry.getSize(); | |||
} | |||
} | |||
} | |||
/** | |||
* Close an entry. This method MUST be called for all file | |||
@@ -222,39 +222,38 @@ public class TarOutputStream extends FilterOutputStream { | |||
this.currBytes += this.assemLen; | |||
this.assemLen = 0; | |||
} | |||
} | |||
if (this.currBytes < this.currSize) { | |||
throw new IOException("entry closed at '" + this.currBytes | |||
+ "' before the '" + this.currSize | |||
throw new IOException("entry closed at '" + this.currBytes | |||
+ "' before the '" + this.currSize | |||
+ "' bytes specified in the header were written"); | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* Writes a byte to the current tar archive entry. | |||
* | |||
* | |||
* This method simply calls read( byte[], int, int ). | |||
* | |||
* | |||
* @param b The byte written. | |||
*/ | |||
public void write(int b) throws IOException { | |||
this.oneBuf[0] = (byte) b; | |||
this.write(this.oneBuf, 0, 1); | |||
} | |||
} | |||
/** | |||
* Writes bytes to the current tar archive entry. | |||
* | |||
* | |||
* This method simply calls write( byte[], int, int ). | |||
* | |||
* | |||
* @param wBuf The buffer to write to the archive. | |||
* @return The number of bytes read, or -1 at EOF. | |||
*/ | |||
public void write(byte[] wBuf) throws IOException { | |||
this.write(wBuf, 0, wBuf.length); | |||
} | |||
} | |||
/** | |||
* Writes bytes to the current tar archive entry. This method | |||
@@ -264,33 +263,33 @@ public class TarOutputStream extends FilterOutputStream { | |||
* record buffering required by TarBuffer, and manages buffers | |||
* that are not a multiple of recordsize in length, including | |||
* assembling records from small buffers. | |||
* | |||
* | |||
* @param wBuf The buffer to write to the archive. | |||
* @param wOffset The offset in the buffer from which to get bytes. | |||
* @param numToWrite The number of bytes to write. | |||
*/ | |||
public void write(byte[] wBuf, int wOffset, int numToWrite) throws IOException { | |||
if ((this.currBytes + numToWrite) > this.currSize) { | |||
throw new IOException("request to write '" + numToWrite | |||
+ "' bytes exceeds size in header of '" | |||
throw new IOException("request to write '" + numToWrite | |||
+ "' bytes exceeds size in header of '" | |||
+ this.currSize + "' bytes"); | |||
// | |||
// | |||
// We have to deal with assembly!!! | |||
// The programmer can be writing little 32 byte chunks for all | |||
// we know, and we must assemble complete records for writing. | |||
// REVIEW Maybe this should be in TarBuffer? Could that help to | |||
// eliminate some of the buffer copying. | |||
// | |||
} | |||
// | |||
} | |||
if (this.assemLen > 0) { | |||
if ((this.assemLen + numToWrite) >= this.recordBuf.length) { | |||
int aLen = this.recordBuf.length - this.assemLen; | |||
System.arraycopy(this.assemBuf, 0, this.recordBuf, 0, | |||
System.arraycopy(this.assemBuf, 0, this.recordBuf, 0, | |||
this.assemLen); | |||
System.arraycopy(wBuf, wOffset, this.recordBuf, | |||
System.arraycopy(wBuf, wOffset, this.recordBuf, | |||
this.assemLen, aLen); | |||
this.buffer.writeRecord(this.recordBuf); | |||
@@ -299,29 +298,29 @@ public class TarOutputStream extends FilterOutputStream { | |||
numToWrite -= aLen; | |||
this.assemLen = 0; | |||
} else { | |||
System.arraycopy(wBuf, wOffset, this.assemBuf, this.assemLen, | |||
System.arraycopy(wBuf, wOffset, this.assemBuf, this.assemLen, | |||
numToWrite); | |||
wOffset += numToWrite; | |||
this.assemLen += numToWrite; | |||
numToWrite -= numToWrite; | |||
} | |||
} | |||
} | |||
} | |||
// | |||
// | |||
// When we get here we have EITHER: | |||
// o An empty "assemble" buffer. | |||
// o No bytes to write (numToWrite == 0) | |||
// | |||
// | |||
while (numToWrite > 0) { | |||
if (numToWrite < this.recordBuf.length) { | |||
System.arraycopy(wBuf, wOffset, this.assemBuf, this.assemLen, | |||
System.arraycopy(wBuf, wOffset, this.assemBuf, this.assemLen, | |||
numToWrite); | |||
this.assemLen += numToWrite; | |||
break; | |||
} | |||
} | |||
this.buffer.writeRecord(wBuf, wOffset); | |||
@@ -330,8 +329,8 @@ public class TarOutputStream extends FilterOutputStream { | |||
this.currBytes += num; | |||
numToWrite -= num; | |||
wOffset += num; | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* Write an EOF (end of archive) record to the tar archive. | |||
@@ -343,7 +342,7 @@ public class TarOutputStream extends FilterOutputStream { | |||
} | |||
this.buffer.writeRecord(this.recordBuf); | |||
} | |||
} | |||
} | |||
@@ -53,7 +53,7 @@ | |||
*/ | |||
/* | |||
* This package is based on the work done by Timothy Gerard Endres | |||
* This package is based on the work done by Timothy Gerard Endres | |||
* (time@ice.com) to whom the Ant project is very grateful for his great code. | |||
*/ | |||
@@ -61,7 +61,7 @@ package org.apache.tools.tar; | |||
/** | |||
* This class provides static utility methods to work with byte streams. | |||
* | |||
* | |||
* @author Timothy Gerard Endres <a href="mailto:time@ice.com">time@ice.com</a> | |||
* @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">stefano@apache.org</a> | |||
*/ | |||
@@ -70,7 +70,7 @@ public class TarUtils { | |||
/** | |||
* Parse an octal string from a header buffer. This is used for the | |||
* file permission mode value. | |||
* | |||
* | |||
* @param header The header buffer from which to parse. | |||
* @param offset The offset into the buffer from which to parse. | |||
* @param length The number of header bytes to parse. | |||
@@ -84,28 +84,28 @@ public class TarUtils { | |||
for (int i = offset; i < end; ++i) { | |||
if (header[i] == 0) { | |||
break; | |||
} | |||
} | |||
if (header[i] == (byte) ' ' || header[i] == '0') { | |||
if (stillPadding) { | |||
continue; | |||
} | |||
} | |||
if (header[i] == (byte) ' ') { | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
stillPadding = false; | |||
result = (result << 3) + (header[i] - '0'); | |||
} | |||
} | |||
return result; | |||
} | |||
} | |||
/** | |||
* Parse an entry name from a header buffer. | |||
* | |||
* | |||
* @param header The header buffer from which to parse. | |||
* @param offset The offset into the buffer from which to parse. | |||
* @param length The number of header bytes to parse. | |||
@@ -118,17 +118,17 @@ public class TarUtils { | |||
for (int i = offset; i < end; ++i) { | |||
if (header[i] == 0) { | |||
break; | |||
} | |||
} | |||
result.append((char) header[i]); | |||
} | |||
} | |||
return result; | |||
} | |||
} | |||
/** | |||
* Determine the number of bytes in an entry name. | |||
* | |||
* | |||
* @param header The header buffer from which to parse. | |||
* @param offset The offset into the buffer from which to parse. | |||
* @param length The number of header bytes to parse. | |||
@@ -139,18 +139,18 @@ public class TarUtils { | |||
for (i = 0; i < length && i < name.length(); ++i) { | |||
buf[offset + i] = (byte) name.charAt(i); | |||
} | |||
} | |||
for (; i < length; ++i) { | |||
buf[offset + i] = 0; | |||
} | |||
} | |||
return offset + length; | |||
} | |||
} | |||
/** | |||
* Parse an octal integer from a header buffer. | |||
* | |||
* | |||
* @param header The header buffer from which to parse. | |||
* @param offset The offset into the buffer from which to parse. | |||
* @param length The number of header bytes to parse. | |||
@@ -171,19 +171,19 @@ public class TarUtils { | |||
for (long val = value; idx >= 0 && val > 0; --idx) { | |||
buf[offset + idx] = (byte) ((byte) '0' + (byte) (val & 7)); | |||
val = val >> 3; | |||
} | |||
} | |||
} | |||
} | |||
for (; idx >= 0; --idx) { | |||
buf[offset + idx] = (byte) ' '; | |||
} | |||
} | |||
return offset + length; | |||
} | |||
} | |||
/** | |||
* Parse an octal long integer from a header buffer. | |||
* | |||
* | |||
* @param header The header buffer from which to parse. | |||
* @param offset The offset into the buffer from which to parse. | |||
* @param length The number of header bytes to parse. | |||
@@ -196,11 +196,11 @@ public class TarUtils { | |||
System.arraycopy(temp, 0, buf, offset, length); | |||
return offset + length; | |||
} | |||
} | |||
/** | |||
* Parse the checksum octal integer from a header buffer. | |||
* | |||
* | |||
* @param header The header buffer from which to parse. | |||
* @param offset The offset into the buffer from which to parse. | |||
* @param length The number of header bytes to parse. | |||
@@ -214,20 +214,20 @@ public class TarUtils { | |||
return offset + length; | |||
} | |||
/** | |||
/** | |||
* Compute the checksum of a tar entry header. | |||
* | |||
* | |||
* @param buf The tar entry's header buffer. | |||
* @return The computed checksum. | |||
*/ | |||
*/ | |||
public static long computeCheckSum(byte[] buf) { | |||
long sum = 0; | |||
for (int i = 0; i < buf.length; ++i) { | |||
sum += 255 & buf[i]; | |||
} | |||
} | |||
return sum; | |||
} | |||
} | |||
} |