Browse Source

Cleaned up code and made some violations go away

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270928 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 23 years ago
parent
commit
1447e596aa
3 changed files with 429 additions and 459 deletions
  1. +171
    -201
      proposal/myrmidon/src/java/org/apache/aut/tar/TarEntry.java
  2. +147
    -153
      proposal/myrmidon/src/java/org/apache/aut/tar/TarInputStream.java
  3. +111
    -105
      proposal/myrmidon/src/java/org/apache/aut/tar/TarOutputStream.java

+ 171
- 201
proposal/myrmidon/src/java/org/apache/aut/tar/TarEntry.java View File

@@ -51,101 +51,107 @@ import java.util.Date;
* } header; * } header;
* </pre> * </pre>
* *
* @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>
* @author <a href="mailto:time@ice.com">Timothy Gerard Endres</a>
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
*/ */
public class TarEntry implements TarConstants
public class TarEntry
// implements TarConstants
{ {
/**
* The length of the name field in a header buffer.
*/
public static final int NAMELEN = 100;

/** /**
* The entry's modification time. * The entry's modification time.
*/ */
private int checkSum;
private int m_checkSum;

/** /**
* The entry's group name. * The entry's group name.
*/ */
private int devMajor;
private int m_devMajor;

/** /**
* The entry's major device number. * The entry's major device number.
*/ */
private int devMinor;
private int m_devMinor;

/** /**
* The entry's minor device number. * The entry's minor device number.
*/ */
private File file;
private File m_file;

/** /**
* The entry's user id. * The entry's user id.
*/ */
private int groupId;
private int m_groupId;

/** /**
* The entry's user name. * The entry's user name.
*/ */
private StringBuffer groupName;
private StringBuffer m_groupName;

/** /**
* The entry's checksum. * The entry's checksum.
*/ */
private byte linkFlag;
private byte m_linkFlag;

/** /**
* The entry's link flag. * The entry's link flag.
*/ */
private StringBuffer linkName;
private StringBuffer m_linkName;

/** /**
* The entry's link name. * The entry's link name.
*/ */
private StringBuffer magic;
private StringBuffer m_magic;

/** /**
* The entry's size. * The entry's size.
*/ */
private long modTime;
private long m_modTime;

/** /**
* The entry's name. * The entry's name.
*/ */
private int mode;
private int m_mode;

private StringBuffer m_name;


private StringBuffer name;
/** /**
* The entry's group id. * The entry's group id.
*/ */
private long size;
private long m_size;

/** /**
* The entry's permission mode. * The entry's permission mode.
*/ */
private int userId;
private int m_userID;

/** /**
* The entry's magic tag. * The entry's magic tag.
*/ */
private StringBuffer userName;
private StringBuffer m_userName;


/** /**
* Construct an entry with only a name. This allows the programmer to * Construct an entry with only a name. This allows the programmer to
* construct the entry's header "by hand". File is set to null. * construct the entry's header "by hand". File is set to null.
*
* @param name Description of Parameter
*/ */
public TarEntry( String name )
public TarEntry( final String name )
{ {
this(); this();


boolean isDir = name.endsWith( "/" );

this.checkSum = 0;
this.devMajor = 0;
this.devMinor = 0;
this.name = new StringBuffer( name );
this.mode = isDir ? 040755 : 0100644;
this.linkFlag = isDir ? LF_DIR : LF_NORMAL;
this.userId = 0;
this.groupId = 0;
this.size = 0;
this.checkSum = 0;
this.modTime = ( new Date() ).getTime() / 1000;
this.linkName = new StringBuffer( "" );
this.userName = new StringBuffer( "" );
this.groupName = new StringBuffer( "" );
this.devMajor = 0;
this.devMinor = 0;
final boolean isDir = name.endsWith( "/" );


m_name = new StringBuffer( name );
m_mode = isDir ? 040755 : 0100644;
m_linkFlag = isDir ? TarConstants.LF_DIR : TarConstants.LF_NORMAL;
m_modTime = ( new Date() ).getTime() / 1000;
m_linkName = new StringBuffer( "" );
m_userName = new StringBuffer( "" );
m_groupName = new StringBuffer( "" );
} }


/** /**
@@ -154,10 +160,10 @@ public class TarEntry implements TarConstants
* @param name Description of Parameter * @param name Description of Parameter
* @param linkFlag Description of Parameter * @param linkFlag Description of Parameter
*/ */
public TarEntry( String name, byte linkFlag )
public TarEntry( final String name, final byte linkFlag )
{ {
this( name ); this( name );
this.linkFlag = linkFlag;
m_linkFlag = linkFlag;
} }


/** /**
@@ -166,33 +172,32 @@ public class TarEntry implements TarConstants
* *
* @param file The file that the entry represents. * @param file The file that the entry represents.
*/ */
public TarEntry( File file )
public TarEntry( final File file )
{ {
this(); this();


this.file = file;
m_file = file;


String name = file.getPath(); String name = file.getPath();
String osname = System.getProperty( "os.name" );
final String osname = System.getProperty( "os.name" );


if( osname != null ) if( osname != null )
{ {

// Strip off drive letters! // Strip off drive letters!
// REVIEW Would a better check be "(File.separator == '\')"? // REVIEW Would a better check be "(File.separator == '\')"?
String win32Prefix = "Windows";
String prefix = osname.substring( 0, win32Prefix.length() );
final String win32Prefix = "Windows";
final String prefix = osname.substring( 0, win32Prefix.length() );


if( prefix.equalsIgnoreCase( win32Prefix ) ) if( prefix.equalsIgnoreCase( win32Prefix ) )
{ {
if( name.length() > 2 ) if( name.length() > 2 )
{ {
char ch1 = name.charAt( 0 );
char ch2 = name.charAt( 1 );
final char ch1 = name.charAt( 0 );
final char ch2 = name.charAt( 1 );


if( ch2 == ':'
&& ( ( ch1 >= 'a' && ch1 <= 'z' )
|| ( ch1 >= 'A' && ch1 <= 'Z' ) ) )
if( ch2 == ':' &&
( ( ch1 >= 'a' && ch1 <= 'z' ) ||
( ch1 >= 'A' && ch1 <= 'Z' ) ) )
{ {
name = name.substring( 2 ); name = name.substring( 2 );
} }
@@ -200,7 +205,7 @@ public class TarEntry implements TarConstants
} }
else if( osname.toLowerCase().indexOf( "netware" ) > -1 ) else if( osname.toLowerCase().indexOf( "netware" ) > -1 )
{ {
int colon = name.indexOf( ':' );
final int colon = name.indexOf( ':' );
if( colon != -1 ) if( colon != -1 )
{ {
name = name.substring( colon + 1 ); name = name.substring( colon + 1 );
@@ -218,68 +223,60 @@ public class TarEntry implements TarConstants
name = name.substring( 1 ); name = name.substring( 1 );
} }


this.linkName = new StringBuffer( "" );
this.name = new StringBuffer( name );
m_linkName = new StringBuffer( "" );
m_name = new StringBuffer( name );


if( file.isDirectory() ) if( file.isDirectory() )
{ {
this.mode = 040755;
this.linkFlag = LF_DIR;
m_mode = 040755;
m_linkFlag = TarConstants.LF_DIR;


if( this.name.charAt( this.name.length() - 1 ) != '/' )
if( m_name.charAt( m_name.length() - 1 ) != '/' )
{ {
this.name.append( "/" );
m_name.append( "/" );
} }
} }
else else
{ {
this.mode = 0100644;
this.linkFlag = LF_NORMAL;
m_mode = 0100644;
m_linkFlag = TarConstants.LF_NORMAL;
} }


this.size = file.length();
this.modTime = file.lastModified() / 1000;
this.checkSum = 0;
this.devMajor = 0;
this.devMinor = 0;
m_size = file.length();
m_modTime = file.lastModified() / 1000;
m_checkSum = 0;
m_devMajor = 0;
m_devMinor = 0;
} }


/** /**
* Construct an entry from an archive's header bytes. File is set to null. * Construct an entry from an archive's header bytes. File is set to null.
* *
* @param headerBuf The header bytes from a tar archive entry.
* @param header The header bytes from a tar archive entry.
*/ */
public TarEntry( byte[] headerBuf )
public TarEntry( final byte[] header )
{ {
this(); this();
this.parseTarHeader( headerBuf );
parseTarHeader( header );
} }


/**
* The entry's file reference
*/

/** /**
* Construct an empty entry and prepares the header values. * Construct an empty entry and prepares the header values.
*/ */
private TarEntry() private TarEntry()
{ {
this.magic = new StringBuffer( TMAGIC );
this.name = new StringBuffer();
this.linkName = new StringBuffer();
m_magic = new StringBuffer( TarConstants.TMAGIC );
m_name = new StringBuffer();
m_linkName = new StringBuffer();


String user = System.getProperty( "user.name", "" ); String user = System.getProperty( "user.name", "" );

if( user.length() > 31 ) if( user.length() > 31 )
{ {
user = user.substring( 0, 31 ); user = user.substring( 0, 31 );
} }


this.userId = 0;
this.groupId = 0;
this.userName = new StringBuffer( user );
this.groupName = new StringBuffer( "" );
this.file = null;
m_userName = new StringBuffer( user );
m_groupName = new StringBuffer( "" );
} }


/** /**
@@ -287,9 +284,9 @@ public class TarEntry implements TarConstants
* *
* @param groupId This entry's new group id. * @param groupId This entry's new group id.
*/ */
public void setGroupId( int groupId )
public void setGroupId( final int groupId )
{ {
this.groupId = groupId;
m_groupId = groupId;
} }


/** /**
@@ -297,21 +294,9 @@ public class TarEntry implements TarConstants
* *
* @param groupName This entry's new group name. * @param groupName This entry's new group name.
*/ */
public void setGroupName( String groupName )
{
this.groupName = new StringBuffer( groupName );
}

/**
* Convenience method to set this entry's group and user ids.
*
* @param userId This entry's new user id.
* @param groupId This entry's new group id.
*/
public void setIds( int userId, int groupId )
public void setGroupName( final String groupName )
{ {
this.setUserId( userId );
this.setGroupId( groupId );
m_groupName = new StringBuffer( groupName );
} }


/** /**
@@ -320,9 +305,9 @@ public class TarEntry implements TarConstants
* *
* @param time This entry's new modification time. * @param time This entry's new modification time.
*/ */
public void setModTime( long time )
public void setModTime( final long time )
{ {
this.modTime = time / 1000;
m_modTime = time / 1000;
} }


/** /**
@@ -330,9 +315,9 @@ public class TarEntry implements TarConstants
* *
* @param time This entry's new modification time. * @param time This entry's new modification time.
*/ */
public void setModTime( Date time )
public void setModTime( final Date time )
{ {
this.modTime = time.getTime() / 1000;
m_modTime = time.getTime() / 1000;
} }


/** /**
@@ -340,9 +325,9 @@ public class TarEntry implements TarConstants
* *
* @param mode The new Mode value * @param mode The new Mode value
*/ */
public void setMode( int mode )
public void setMode( final int mode )
{ {
this.mode = mode;
m_mode = mode;
} }


/** /**
@@ -350,21 +335,9 @@ public class TarEntry implements TarConstants
* *
* @param name This entry's new name. * @param name This entry's new name.
*/ */
public void setName( String name )
public void setName( final String name )
{ {
this.name = new StringBuffer( name );
}

/**
* Convenience method to set this entry's group and user names.
*
* @param userName This entry's new user name.
* @param groupName This entry's new group name.
*/
public void setNames( String userName, String groupName )
{
this.setUserName( userName );
this.setGroupName( groupName );
m_name = new StringBuffer( name );
} }


/** /**
@@ -372,9 +345,9 @@ public class TarEntry implements TarConstants
* *
* @param size This entry's new file size. * @param size This entry's new file size.
*/ */
public void setSize( long size )
public void setSize( final long size )
{ {
this.size = size;
m_size = size;
} }


/** /**
@@ -382,9 +355,9 @@ public class TarEntry implements TarConstants
* *
* @param userId This entry's new user id. * @param userId This entry's new user id.
*/ */
public void setUserId( int userId )
public void setUserId( final int userId )
{ {
this.userId = userId;
m_userID = userId;
} }


/** /**
@@ -392,9 +365,9 @@ public class TarEntry implements TarConstants
* *
* @param userName This entry's new user name. * @param userName This entry's new user name.
*/ */
public void setUserName( String userName )
public void setUserName( final String userName )
{ {
this.userName = new StringBuffer( userName );
m_userName = new StringBuffer( userName );
} }


/** /**
@@ -405,17 +378,17 @@ public class TarEntry implements TarConstants
*/ */
public TarEntry[] getDirectoryEntries() public TarEntry[] getDirectoryEntries()
{ {
if( this.file == null || !this.file.isDirectory() )
if( null == m_file || !m_file.isDirectory() )
{ {
return new TarEntry[ 0 ]; return new TarEntry[ 0 ];
} }


String[] list = this.file.list();
TarEntry[] result = new TarEntry[ list.length ];
final String[] list = m_file.list();
final TarEntry[] result = new TarEntry[ list.length ];


for( int i = 0; i < list.length; ++i ) for( int i = 0; i < list.length; ++i )
{ {
result[ i ] = new TarEntry( new File( this.file, list[ i ] ) );
result[ i ] = new TarEntry( new File( m_file, list[ i ] ) );
} }


return result; return result;
@@ -428,7 +401,7 @@ public class TarEntry implements TarConstants
*/ */
public File getFile() public File getFile()
{ {
return this.file;
return m_file;
} }


/** /**
@@ -438,7 +411,7 @@ public class TarEntry implements TarConstants
*/ */
public int getGroupId() public int getGroupId()
{ {
return this.groupId;
return m_groupId;
} }


/** /**
@@ -448,7 +421,7 @@ public class TarEntry implements TarConstants
*/ */
public String getGroupName() public String getGroupName()
{ {
return this.groupName.toString();
return m_groupName.toString();
} }


/** /**
@@ -458,7 +431,7 @@ public class TarEntry implements TarConstants
*/ */
public Date getModTime() public Date getModTime()
{ {
return new Date( this.modTime * 1000 );
return new Date( m_modTime * 1000 );
} }


/** /**
@@ -468,7 +441,7 @@ public class TarEntry implements TarConstants
*/ */
public int getMode() public int getMode()
{ {
return this.mode;
return m_mode;
} }


/** /**
@@ -478,7 +451,7 @@ public class TarEntry implements TarConstants
*/ */
public String getName() public String getName()
{ {
return this.name.toString();
return m_name.toString();
} }


/** /**
@@ -488,7 +461,7 @@ public class TarEntry implements TarConstants
*/ */
public long getSize() public long getSize()
{ {
return this.size;
return m_size;
} }


/** /**
@@ -498,7 +471,7 @@ public class TarEntry implements TarConstants
*/ */
public int getUserId() public int getUserId()
{ {
return this.userId;
return m_userID;
} }


/** /**
@@ -508,7 +481,7 @@ public class TarEntry implements TarConstants
*/ */
public String getUserName() public String getUserName()
{ {
return this.userName.toString();
return m_userName.toString();
} }


/** /**
@@ -516,12 +489,12 @@ public class TarEntry implements TarConstants
* is determined by the name of the descendant starting with this entry's * is determined by the name of the descendant starting with this entry's
* name. * name.
* *
* @param desc Entry to be checked as a descendent of this.
* @return True if entry is a descendant of this.
* @param desc Entry to be checked as a descendent of
* @return True if entry is a descendant of
*/ */
public boolean isDescendent( TarEntry desc )
public boolean isDescendent( final TarEntry desc )
{ {
return desc.getName().startsWith( this.getName() );
return desc.getName().startsWith( getName() );
} }


/** /**
@@ -531,17 +504,17 @@ public class TarEntry implements TarConstants
*/ */
public boolean isDirectory() public boolean isDirectory()
{ {
if( this.file != null )
if( m_file != null )
{ {
return this.file.isDirectory();
return m_file.isDirectory();
} }


if( this.linkFlag == LF_DIR )
if( m_linkFlag == TarConstants.LF_DIR )
{ {
return true; return true;
} }


if( this.getName().endsWith( "/" ) )
if( getName().endsWith( "/" ) )
{ {
return true; return true;
} }
@@ -556,21 +529,20 @@ public class TarEntry implements TarConstants
*/ */
public boolean isGNULongNameEntry() public boolean isGNULongNameEntry()
{ {
return linkFlag == LF_GNUTYPE_LONGNAME &&
name.toString().equals( GNU_LONGLINK );
return m_linkFlag == TarConstants.LF_GNUTYPE_LONGNAME &&
m_name.toString().equals( TarConstants.GNU_LONGLINK );
} }


/** /**
* Determine if the two entries are equal. Equality is determined by the * Determine if the two entries are equal. Equality is determined by the
* header names being equal. * header names being equal.
* *
* @param it Description of Parameter
* @return it Entry to be checked for equality.
* @param other Entry to be checked for equality.
* @return True if the entries are equal. * @return True if the entries are equal.
*/ */
public boolean equals( TarEntry it )
public boolean equals( final TarEntry other )
{ {
return this.getName().equals( it.getName() );
return getName().equals( other.getName() );
} }


/** /**
@@ -578,36 +550,36 @@ public class TarEntry implements TarConstants
* *
* @param header The tar entry header buffer to get information from. * @param header The tar entry header buffer to get information from.
*/ */
public void parseTarHeader( byte[] header )
private void parseTarHeader( final byte[] header )
{ {
int offset = 0; int offset = 0;


this.name = TarUtils.parseName( header, offset, NAMELEN );
m_name = TarUtils.parseName( header, offset, NAMELEN );
offset += NAMELEN; offset += NAMELEN;
this.mode = (int)TarUtils.parseOctal( header, offset, MODELEN );
offset += MODELEN;
this.userId = (int)TarUtils.parseOctal( header, offset, UIDLEN );
offset += UIDLEN;
this.groupId = (int)TarUtils.parseOctal( header, offset, GIDLEN );
offset += GIDLEN;
this.size = TarUtils.parseOctal( header, offset, SIZELEN );
offset += SIZELEN;
this.modTime = TarUtils.parseOctal( header, offset, MODTIMELEN );
offset += MODTIMELEN;
this.checkSum = (int)TarUtils.parseOctal( header, offset, CHKSUMLEN );
offset += CHKSUMLEN;
this.linkFlag = header[ offset++ ];
this.linkName = TarUtils.parseName( header, offset, NAMELEN );
m_mode = (int)TarUtils.parseOctal( header, offset, TarConstants.MODELEN );
offset += TarConstants.MODELEN;
m_userID = (int)TarUtils.parseOctal( header, offset, TarConstants.UIDLEN );
offset += TarConstants.UIDLEN;
m_groupId = (int)TarUtils.parseOctal( header, offset, TarConstants.GIDLEN );
offset += TarConstants.GIDLEN;
m_size = TarUtils.parseOctal( header, offset, TarConstants.SIZELEN );
offset += TarConstants.SIZELEN;
m_modTime = TarUtils.parseOctal( header, offset, TarConstants.MODTIMELEN );
offset += TarConstants.MODTIMELEN;
m_checkSum = (int)TarUtils.parseOctal( header, offset, TarConstants.CHKSUMLEN );
offset += TarConstants.CHKSUMLEN;
m_linkFlag = header[ offset++ ];
m_linkName = TarUtils.parseName( header, offset, NAMELEN );
offset += NAMELEN; offset += NAMELEN;
this.magic = TarUtils.parseName( header, offset, MAGICLEN );
offset += MAGICLEN;
this.userName = TarUtils.parseName( header, offset, UNAMELEN );
offset += UNAMELEN;
this.groupName = TarUtils.parseName( header, offset, GNAMELEN );
offset += GNAMELEN;
this.devMajor = (int)TarUtils.parseOctal( header, offset, DEVLEN );
offset += DEVLEN;
this.devMinor = (int)TarUtils.parseOctal( header, offset, DEVLEN );
m_magic = TarUtils.parseName( header, offset, TarConstants.MAGICLEN );
offset += TarConstants.MAGICLEN;
m_userName = TarUtils.parseName( header, offset, TarConstants.UNAMELEN );
offset += TarConstants.UNAMELEN;
m_groupName = TarUtils.parseName( header, offset, TarConstants.GNAMELEN );
offset += TarConstants.GNAMELEN;
m_devMajor = (int)TarUtils.parseOctal( header, offset, TarConstants.DEVLEN );
offset += TarConstants.DEVLEN;
m_devMinor = (int)TarUtils.parseOctal( header, offset, TarConstants.DEVLEN );
} }


/** /**
@@ -615,39 +587,37 @@ public class TarEntry implements TarConstants
* *
* @param outbuf The tar entry header buffer to fill in. * @param outbuf The tar entry header buffer to fill in.
*/ */
public void writeEntryHeader( byte[] outbuf )
public void writeEntryHeader( final byte[] buffer )
{ {
int offset = 0; int offset = 0;


offset = TarUtils.getNameBytes( this.name, outbuf, offset, NAMELEN );
offset = TarUtils.getOctalBytes( this.mode, outbuf, offset, MODELEN );
offset = TarUtils.getOctalBytes( this.userId, outbuf, offset, UIDLEN );
offset = TarUtils.getOctalBytes( this.groupId, outbuf, offset, GIDLEN );
offset = TarUtils.getLongOctalBytes( this.size, outbuf, offset, SIZELEN );
offset = TarUtils.getLongOctalBytes( this.modTime, outbuf, offset, MODTIMELEN );
offset = TarUtils.getNameBytes( m_name, buffer, offset, NAMELEN );
offset = TarUtils.getOctalBytes( m_mode, buffer, offset, TarConstants.MODELEN );
offset = TarUtils.getOctalBytes( m_userID, buffer, offset, TarConstants.UIDLEN );
offset = TarUtils.getOctalBytes( m_groupId, buffer, offset, TarConstants.GIDLEN );
offset = TarUtils.getLongOctalBytes( m_size, buffer, offset, TarConstants.SIZELEN );
offset = TarUtils.getLongOctalBytes( m_modTime, buffer, offset, TarConstants.MODTIMELEN );


int csOffset = offset;

for( int c = 0; c < CHKSUMLEN; ++c )
final int checkSumOffset = offset;
for( int i = 0; i < TarConstants.CHKSUMLEN; ++i )
{ {
outbuf[ offset++ ] = (byte)' ';
buffer[ offset++ ] = (byte)' ';
} }


outbuf[ offset++ ] = this.linkFlag;
offset = TarUtils.getNameBytes( this.linkName, outbuf, offset, NAMELEN );
offset = TarUtils.getNameBytes( this.magic, outbuf, offset, MAGICLEN );
offset = TarUtils.getNameBytes( this.userName, outbuf, offset, UNAMELEN );
offset = TarUtils.getNameBytes( this.groupName, outbuf, offset, GNAMELEN );
offset = TarUtils.getOctalBytes( this.devMajor, outbuf, offset, DEVLEN );
offset = TarUtils.getOctalBytes( this.devMinor, outbuf, offset, DEVLEN );
buffer[ offset++ ] = m_linkFlag;
offset = TarUtils.getNameBytes( m_linkName, buffer, offset, NAMELEN );
offset = TarUtils.getNameBytes( m_magic, buffer, offset, TarConstants.MAGICLEN );
offset = TarUtils.getNameBytes( m_userName, buffer, offset, TarConstants.UNAMELEN );
offset = TarUtils.getNameBytes( m_groupName, buffer, offset, TarConstants.GNAMELEN );
offset = TarUtils.getOctalBytes( m_devMajor, buffer, offset, TarConstants.DEVLEN );
offset = TarUtils.getOctalBytes( m_devMinor, buffer, offset, TarConstants.DEVLEN );


while( offset < outbuf.length )
while( offset < buffer.length )
{ {
outbuf[ offset++ ] = 0;
buffer[ offset++ ] = 0;
} }


long checkSum = TarUtils.computeCheckSum( outbuf );

TarUtils.getCheckSumOctalBytes( checkSum, outbuf, csOffset, CHKSUMLEN );
final long checkSum = TarUtils.computeCheckSum( buffer );
TarUtils.getCheckSumOctalBytes( checkSum, buffer, checkSumOffset, TarConstants.CHKSUMLEN );
} }
} }

+ 147
- 153
proposal/myrmidon/src/java/org/apache/aut/tar/TarInputStream.java View File

@@ -17,41 +17,40 @@ import java.io.OutputStream;
* provided to position at each successive entry in the archive, and the read * provided to position at each successive entry in the archive, and the read
* each entry as a normal input stream using read(). * each entry as a normal input stream using read().
* *
* @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>
* @author <a href="mailto:time@ice.com">Timothy Gerard Endres</a>
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
*/ */
public class TarInputStream extends FilterInputStream
public class TarInputStream
extends FilterInputStream
{ {
protected TarBuffer buffer;
protected TarEntry currEntry;

protected boolean debug;
protected int entryOffset;
protected int entrySize;
protected boolean hasHitEOF;
protected byte[] oneBuf;
protected byte[] readBuf;

public TarInputStream( InputStream is )
private TarBuffer m_buffer;
private TarEntry m_currEntry;
private boolean m_debug;
private int m_entryOffset;
private int m_entrySize;
private boolean m_hasHitEOF;
private byte[] m_oneBuf;
private byte[] m_readBuf;

public TarInputStream( final InputStream input )
{ {
this( is, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE );
this( input, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE );
} }


public TarInputStream( InputStream is, int blockSize )
public TarInputStream( final InputStream input, final int blockSize )
{ {
this( is, blockSize, TarBuffer.DEFAULT_RCDSIZE );
this( input, blockSize, TarBuffer.DEFAULT_RCDSIZE );
} }


public TarInputStream( InputStream is, int blockSize, int recordSize )
public TarInputStream( final InputStream input,
final int blockSize,
final int recordSize )
{ {
super( is );
super( input );


this.buffer = new TarBuffer( is, blockSize, recordSize );
this.readBuf = null;
this.oneBuf = new byte[ 1 ];
this.debug = false;
this.hasHitEOF = false;
m_buffer = new TarBuffer( input, blockSize, recordSize );
m_oneBuf = new byte[ 1 ];
} }


/** /**
@@ -59,10 +58,10 @@ public class TarInputStream extends FilterInputStream
* *
* @param debug The new Debug value * @param debug The new Debug value
*/ */
public void setDebug( boolean debug )
public void setDebug( final boolean debug )
{ {
this.debug = debug;
this.buffer.setDebug( debug );
m_debug = debug;
m_buffer.setDebug( debug );
} }


/** /**
@@ -79,119 +78,113 @@ public class TarInputStream extends FilterInputStream
public TarEntry getNextEntry() public TarEntry getNextEntry()
throws IOException throws IOException
{ {
if( this.hasHitEOF )
if( m_hasHitEOF )
{ {
return null; return null;
} }


if( this.currEntry != null )
if( m_currEntry != null )
{ {
int numToSkip = this.entrySize - this.entryOffset;
final int numToSkip = m_entrySize - m_entryOffset;


if( this.debug )
if( m_debug )
{ {
System.err.println( "TarInputStream: SKIP currENTRY '"
+ this.currEntry.getName() + "' SZ "
+ this.entrySize + " OFF "
+ this.entryOffset + " skipping "
+ numToSkip + " bytes" );
final String message = "TarInputStream: SKIP currENTRY '" +
m_currEntry.getName() + "' SZ " + m_entrySize +
" OFF " + m_entryOffset + " skipping " + numToSkip + " bytes";
debug( message );
} }


if( numToSkip > 0 ) if( numToSkip > 0 )
{ {
this.skip( numToSkip );
skip( numToSkip );
} }


this.readBuf = null;
m_readBuf = null;
} }


byte[] headerBuf = this.buffer.readRecord();

final byte[] headerBuf = m_buffer.readRecord();
if( headerBuf == null ) if( headerBuf == null )
{ {
if( this.debug )
if( m_debug )
{ {
System.err.println( "READ NULL RECORD" );
debug( "READ NULL RECORD" );
} }
this.hasHitEOF = true;
m_hasHitEOF = true;
} }
else if( this.buffer.isEOFRecord( headerBuf ) )
else if( m_buffer.isEOFRecord( headerBuf ) )
{ {
if( this.debug )
if( m_debug )
{ {
System.err.println( "READ EOF RECORD" );
debug( "READ EOF RECORD" );
} }
this.hasHitEOF = true;
m_hasHitEOF = true;
} }


if( this.hasHitEOF )
if( m_hasHitEOF )
{ {
this.currEntry = null;
m_currEntry = null;
} }
else else
{ {
this.currEntry = new TarEntry( headerBuf );
m_currEntry = new TarEntry( headerBuf );


if( !( headerBuf[ 257 ] == 'u' && headerBuf[ 258 ] == 's'
&& headerBuf[ 259 ] == 't' && headerBuf[ 260 ] == 'a'
&& headerBuf[ 261 ] == 'r' ) )
if( !( headerBuf[ 257 ] == 'u' && headerBuf[ 258 ] == 's' &&
headerBuf[ 259 ] == 't' && headerBuf[ 260 ] == 'a' &&
headerBuf[ 261 ] == 'r' ) )
{ {
this.entrySize = 0;
this.entryOffset = 0;
this.currEntry = null;

throw new IOException( "bad header in block "
+ this.buffer.getCurrentBlockNum()
+ " record "
+ this.buffer.getCurrentRecordNum()
+ ", " +
"header magic is not 'ustar', but '"
+ headerBuf[ 257 ]
+ headerBuf[ 258 ]
+ headerBuf[ 259 ]
+ headerBuf[ 260 ]
+ headerBuf[ 261 ]
+ "', or (dec) "
+ ( (int)headerBuf[ 257 ] )
+ ", "
+ ( (int)headerBuf[ 258 ] )
+ ", "
+ ( (int)headerBuf[ 259 ] )
+ ", "
+ ( (int)headerBuf[ 260 ] )
+ ", "
+ ( (int)headerBuf[ 261 ] ) );
m_entrySize = 0;
m_entryOffset = 0;
m_currEntry = null;

final String message = "bad header in block " +
m_buffer.getCurrentBlockNum() +
" record " + m_buffer.getCurrentRecordNum() + ", " +
"header magic is not 'ustar', but '" +
headerBuf[ 257 ] +
headerBuf[ 258 ] +
headerBuf[ 259 ] +
headerBuf[ 260 ] +
headerBuf[ 261 ] +
"', or (dec) " +
( (int)headerBuf[ 257 ] ) + ", " +
( (int)headerBuf[ 258 ] ) + ", " +
( (int)headerBuf[ 259 ] ) + ", " +
( (int)headerBuf[ 260 ] ) + ", " +
( (int)headerBuf[ 261 ] );

throw new IOException( message );
} }


if( this.debug )
if( m_debug )
{ {
System.err.println( "TarInputStream: SET CURRENTRY '"
+ this.currEntry.getName()
+ "' size = "
+ this.currEntry.getSize() );
final String message = "TarInputStream: SET CURRENTRY '" +
m_currEntry.getName() + "' size = " + m_currEntry.getSize();
debug( message );
} }


this.entryOffset = 0;
m_entryOffset = 0;


// REVIEW How do we resolve this discrepancy?! // REVIEW How do we resolve this discrepancy?!
this.entrySize = (int)this.currEntry.getSize();
m_entrySize = (int)m_currEntry.getSize();
} }


if( this.currEntry != null && this.currEntry.isGNULongNameEntry() )
if( null != m_currEntry && m_currEntry.isGNULongNameEntry() )
{ {
// read in the name // read in the name
StringBuffer longName = new StringBuffer();
byte[] buffer = new byte[ 256 ];
final StringBuffer longName = new StringBuffer();
final byte[] buffer = new byte[ 256 ];
int length = 0; int length = 0;
while( ( length = read( buffer ) ) >= 0 ) while( ( length = read( buffer ) ) >= 0 )
{ {
longName.append( new String( buffer, 0, length ) );
final String str = new String( buffer, 0, length );
longName.append( str );
} }
getNextEntry(); getNextEntry();
this.currEntry.setName( longName.toString() );
m_currEntry.setName( longName.toString() );
} }


return this.currEntry;
return m_currEntry;
} }


/** /**
@@ -201,7 +194,7 @@ public class TarInputStream extends FilterInputStream
*/ */
public int getRecordSize() public int getRecordSize()
{ {
return this.buffer.getRecordSize();
return m_buffer.getRecordSize();
} }


/** /**
@@ -217,18 +210,16 @@ public class TarInputStream extends FilterInputStream
public int available() public int available()
throws IOException throws IOException
{ {
return this.entrySize - this.entryOffset;
return m_entrySize - m_entryOffset;
} }


/** /**
* Closes this stream. Calls the TarBuffer's close() method. * Closes this stream. Calls the TarBuffer's close() method.
*
* @exception IOException Description of Exception
*/ */
public void close() public void close()
throws IOException throws IOException
{ {
this.buffer.close();
m_buffer.close();
} }


/** /**
@@ -238,21 +229,19 @@ public class TarInputStream extends FilterInputStream
* @param out The OutputStream into which to write the entry's data. * @param out The OutputStream into which to write the entry's data.
* @exception IOException Description of Exception * @exception IOException Description of Exception
*/ */
public void copyEntryContents( OutputStream out )
public void copyEntryContents( final OutputStream output )
throws IOException throws IOException
{ {
byte[] buf = new byte[ 32 * 1024 ];

final byte[] buffer = new byte[ 32 * 1024 ];
while( true ) while( true )
{ {
int numRead = this.read( buf, 0, buf.length );

final int numRead = read( buffer, 0, buffer.length );
if( numRead == -1 ) if( numRead == -1 )
{ {
break; break;
} }


out.write( buf, 0, numRead );
output.write( buffer, 0, numRead );
} }
} }


@@ -285,15 +274,14 @@ public class TarInputStream extends FilterInputStream
public int read() public int read()
throws IOException throws IOException
{ {
int num = this.read( this.oneBuf, 0, 1 );

final int num = read( m_oneBuf, 0, 1 );
if( num == -1 ) if( num == -1 )
{ {
return num; return num;
} }
else else
{ {
return (int)this.oneBuf[ 0 ];
return (int)m_oneBuf[ 0 ];
} }
} }


@@ -305,10 +293,10 @@ public class TarInputStream extends FilterInputStream
* @return The number of bytes read, or -1 at EOF. * @return The number of bytes read, or -1 at EOF.
* @exception IOException Description of Exception * @exception IOException Description of Exception
*/ */
public int read( byte[] buf )
public int read( final byte[] buffer )
throws IOException throws IOException
{ {
return this.read( buf, 0, buf.length );
return read( buffer, 0, buffer.length );
} }


/** /**
@@ -318,86 +306,89 @@ public class TarInputStream extends FilterInputStream
* *
* @param buf The buffer into which to place bytes read. * @param buf The buffer into which to place bytes read.
* @param offset The offset at which to place bytes read. * @param offset The offset at which to place bytes read.
* @param numToRead The number of bytes to read.
* @param count The number of bytes to read.
* @return The number of bytes read, or -1 at EOF. * @return The number of bytes read, or -1 at EOF.
* @exception IOException Description of Exception
*/ */
public int read( byte[] buf, int offset, int numToRead )
public int read( final byte[] buffer,
final int offset,
final int count )
throws IOException throws IOException
{ {
int position = offset;
int numToRead = count;
int totalRead = 0; int totalRead = 0;


if( this.entryOffset >= this.entrySize )
if( m_entryOffset >= m_entrySize )
{ {
return -1; return -1;
} }


if( ( numToRead + this.entryOffset ) > this.entrySize )
if( ( numToRead + m_entryOffset ) > m_entrySize )
{ {
numToRead = ( this.entrySize - this.entryOffset );
numToRead = ( m_entrySize - m_entryOffset );
} }


if( this.readBuf != null )
if( null != m_readBuf )
{ {
int sz = ( numToRead > this.readBuf.length ) ? this.readBuf.length
: numToRead;
final int size =
( numToRead > m_readBuf.length ) ? m_readBuf.length : numToRead;


System.arraycopy( this.readBuf, 0, buf, offset, sz );
System.arraycopy( m_readBuf, 0, buffer, position, size );


if( sz >= this.readBuf.length )
if( size >= m_readBuf.length )
{ {
this.readBuf = null;
m_readBuf = null;
} }
else else
{ {
int newLen = this.readBuf.length - sz;
byte[] newBuf = new byte[ newLen ];
final int newLength = m_readBuf.length - size;
final byte[] newBuffer = new byte[ newLength ];


System.arraycopy( this.readBuf, sz, newBuf, 0, newLen );
System.arraycopy( m_readBuf, size, newBuffer, 0, newLength );


this.readBuf = newBuf;
m_readBuf = newBuffer;
} }


totalRead += sz;
numToRead -= sz;
offset += sz;
totalRead += size;
numToRead -= size;
position += size;
} }


while( numToRead > 0 ) while( numToRead > 0 )
{ {
byte[] rec = this.buffer.readRecord();

if( rec == null )
final byte[] rec = m_buffer.readRecord();
if( null == rec )
{ {
// Unexpected EOF! // Unexpected EOF!
throw new IOException( "unexpected EOF with " + numToRead
+ " bytes unread" );
final String message =
"unexpected EOF with " + numToRead + " bytes unread";
throw new IOException( message );
} }


int sz = numToRead;
int recLen = rec.length;
int size = numToRead;
final int recordLength = rec.length;


if( recLen > sz )
if( recordLength > size )
{ {
System.arraycopy( rec, 0, buf, offset, sz );
System.arraycopy( rec, 0, buffer, position, size );


this.readBuf = new byte[ recLen - sz ];
m_readBuf = new byte[ recordLength - size ];


System.arraycopy( rec, sz, this.readBuf, 0, recLen - sz );
System.arraycopy( rec, size, m_readBuf, 0, recordLength - size );
} }
else else
{ {
sz = recLen;
size = recordLength;


System.arraycopy( rec, 0, buf, offset, recLen );
System.arraycopy( rec, 0, buffer, position, recordLength );
} }


totalRead += sz;
numToRead -= sz;
offset += sz;
totalRead += size;
numToRead -= size;
position += size;
} }


this.entryOffset += totalRead;
m_entryOffset += totalRead;


return totalRead; return totalRead;
} }
@@ -415,24 +406,19 @@ public class TarInputStream extends FilterInputStream
* entry's data if the number to skip extends beyond that point. * entry's data if the number to skip extends beyond that point.
* *
* @param numToSkip The number of bytes to skip. * @param numToSkip The number of bytes to skip.
* @exception IOException Description of Exception
*/ */
public void skip( int numToSkip )
public void skip( final int numToSkip )
throws IOException throws IOException
{ {

// REVIEW // REVIEW
// This is horribly inefficient, but it ensures that we // This is horribly inefficient, but it ensures that we
// properly skip over bytes via the TarBuffer... // properly skip over bytes via the TarBuffer...
// //
byte[] skipBuf = new byte[ 8 * 1024 ];

final byte[] skipBuf = new byte[ 8 * 1024 ];
for( int num = numToSkip; num > 0; ) for( int num = numToSkip; num > 0; )
{ {
int numRead = this.read( skipBuf, 0,
( num > skipBuf.length ? skipBuf.length
: num ) );

final int count = ( num > skipBuf.length ) ? skipBuf.length : num;
final int numRead = read( skipBuf, 0, count );
if( numRead == -1 ) if( numRead == -1 )
{ {
break; break;
@@ -441,4 +427,12 @@ public class TarInputStream extends FilterInputStream
num -= numRead; num -= numRead;
} }
} }

protected void debug( final String message )
{
if( m_debug )
{
System.err.println( message );
}
}
} }

+ 111
- 105
proposal/myrmidon/src/java/org/apache/aut/tar/TarOutputStream.java View File

@@ -17,43 +17,48 @@ import java.io.OutputStream;
* stream using write(). * stream using write().
* *
* @author Timothy Gerard Endres <a href="mailto:time@ice.com">time@ice.com</a> * @author Timothy Gerard Endres <a href="mailto:time@ice.com">time@ice.com</a>
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
*/ */
public class TarOutputStream extends FilterOutputStream
public class TarOutputStream
extends FilterOutputStream
{ {
public final static int LONGFILE_ERROR = 0; public final static int LONGFILE_ERROR = 0;
public final static int LONGFILE_TRUNCATE = 1; public final static int LONGFILE_TRUNCATE = 1;
public final static int LONGFILE_GNU = 2; public final static int LONGFILE_GNU = 2;
protected int longFileMode = LONGFILE_ERROR;
protected byte[] assemBuf;
protected int assemLen;
protected TarBuffer buffer;
protected int currBytes;
protected int currSize;

protected boolean debug;
protected byte[] oneBuf;
protected byte[] recordBuf;

public TarOutputStream( OutputStream os )

private int m_longFileMode = LONGFILE_ERROR;
private byte[] m_assemBuf;
private int m_assemLen;
private TarBuffer m_buffer;
private int m_currBytes;
private int m_currSize;

private boolean m_debug;
private byte[] m_oneBuf;
private byte[] m_recordBuf;

public TarOutputStream( final OutputStream output )
{ {
this( os, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE );
this( output, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE );
} }


public TarOutputStream( OutputStream os, int blockSize )
public TarOutputStream( final OutputStream output, final int blockSize )
{ {
this( os, blockSize, TarBuffer.DEFAULT_RCDSIZE );
this( output, blockSize, TarBuffer.DEFAULT_RCDSIZE );
} }


public TarOutputStream( OutputStream os, int blockSize, int recordSize )
public TarOutputStream( final OutputStream output,
final int blockSize,
final int recordSize )
{ {
super( os );
this.buffer = new TarBuffer( os, blockSize, recordSize );
this.debug = false;
this.assemLen = 0;
this.assemBuf = new byte[ recordSize ];
this.recordBuf = new byte[ recordSize ];
this.oneBuf = new byte[ 1 ];
super( output );
m_buffer = new TarBuffer( output, blockSize, recordSize );
m_debug = false;
m_assemLen = 0;
m_assemBuf = new byte[ recordSize ];
m_recordBuf = new byte[ recordSize ];
m_oneBuf = new byte[ 1 ];
} }


/** /**
@@ -63,7 +68,7 @@ public class TarOutputStream extends FilterOutputStream
*/ */
public void setBufferDebug( boolean debug ) public void setBufferDebug( boolean debug )
{ {
this.buffer.setDebug( debug );
m_buffer.setDebug( debug );
} }


/** /**
@@ -71,14 +76,14 @@ public class TarOutputStream extends FilterOutputStream
* *
* @param debugF True to turn on debugging. * @param debugF True to turn on debugging.
*/ */
public void setDebug( boolean debugF )
public void setDebug( boolean debug )
{ {
this.debug = debugF;
m_debug = debug;
} }


public void setLongFileMode( int longFileMode )
public void setLongFileMode( final int longFileMode )
{ {
this.longFileMode = longFileMode;
m_longFileMode = longFileMode;
} }


/** /**
@@ -88,7 +93,7 @@ public class TarOutputStream extends FilterOutputStream
*/ */
public int getRecordSize() public int getRecordSize()
{ {
return this.buffer.getRecordSize();
return m_buffer.getRecordSize();
} }


/** /**
@@ -100,8 +105,8 @@ public class TarOutputStream extends FilterOutputStream
public void close() public void close()
throws IOException throws IOException
{ {
this.finish();
this.buffer.close();
finish();
m_buffer.close();
} }


/** /**
@@ -116,24 +121,25 @@ public class TarOutputStream extends FilterOutputStream
public void closeEntry() public void closeEntry()
throws IOException throws IOException
{ {
if( this.assemLen > 0 )
if( m_assemLen > 0 )
{ {
for( int i = this.assemLen; i < this.assemBuf.length; ++i )
for( int i = m_assemLen; i < m_assemBuf.length; ++i )
{ {
this.assemBuf[ i ] = 0;
m_assemBuf[ i ] = 0;
} }


this.buffer.writeRecord( this.assemBuf );
m_buffer.writeRecord( m_assemBuf );


this.currBytes += this.assemLen;
this.assemLen = 0;
m_currBytes += m_assemLen;
m_assemLen = 0;
} }


if( this.currBytes < this.currSize )
if( m_currBytes < m_currSize )
{ {
throw new IOException( "entry closed at '" + this.currBytes
+ "' before the '" + this.currSize
+ "' bytes specified in the header were written" );
final String message = "entry closed at '" + m_currBytes +
"' before the '" + m_currSize +
"' bytes specified in the header were written";
throw new IOException( message );
} }
} }


@@ -146,7 +152,7 @@ public class TarOutputStream extends FilterOutputStream
public void finish() public void finish()
throws IOException throws IOException
{ {
this.writeEOFRecord();
writeEOFRecord();
} }


/** /**
@@ -160,18 +166,19 @@ public class TarOutputStream extends FilterOutputStream
* @param entry The TarEntry to be written to the archive. * @param entry The TarEntry to be written to the archive.
* @exception IOException Description of Exception * @exception IOException Description of Exception
*/ */
public void putNextEntry( TarEntry entry )
public void putNextEntry( final TarEntry entry )
throws IOException throws IOException
{ {
if( entry.getName().length() >= TarConstants.NAMELEN )
if( entry.getName().length() >= TarEntry.NAMELEN )
{ {


if( longFileMode == LONGFILE_GNU )
if( m_longFileMode == LONGFILE_GNU )
{ {
// create a TarEntry for the LongLink, the contents // 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 );
final TarEntry longLinkEntry =
new TarEntry( TarConstants.GNU_LONGLINK,
TarConstants.LF_GNUTYPE_LONGNAME );


longLinkEntry.setSize( entry.getName().length() + 1 ); longLinkEntry.setSize( entry.getName().length() + 1 );
putNextEntry( longLinkEntry ); putNextEntry( longLinkEntry );
@@ -179,26 +186,26 @@ public class TarOutputStream extends FilterOutputStream
write( 0 ); write( 0 );
closeEntry(); closeEntry();
} }
else if( longFileMode != LONGFILE_TRUNCATE )
else if( m_longFileMode != LONGFILE_TRUNCATE )
{ {
throw new RuntimeException( "file name '" + entry.getName()
+ "' is too long ( > "
+ TarConstants.NAMELEN + " bytes)" );
final String message = "file name '" + entry.getName() +
"' is too long ( > " + TarEntry.NAMELEN + " bytes)";
throw new IOException( message );
} }
} }


entry.writeEntryHeader( this.recordBuf );
this.buffer.writeRecord( this.recordBuf );
entry.writeEntryHeader( m_recordBuf );
m_buffer.writeRecord( m_recordBuf );


this.currBytes = 0;
m_currBytes = 0;


if( entry.isDirectory() ) if( entry.isDirectory() )
{ {
this.currSize = 0;
m_currSize = 0;
} }
else else
{ {
this.currSize = (int)entry.getSize();
m_currSize = (int)entry.getSize();
} }
} }


@@ -206,15 +213,15 @@ public class TarOutputStream extends FilterOutputStream
* Writes a byte to the current tar archive entry. This method simply calls * Writes a byte to the current tar archive entry. This method simply calls
* read( byte[], int, int ). * read( byte[], int, int ).
* *
* @param b The byte written.
* @param data The byte written.
* @exception IOException Description of Exception * @exception IOException Description of Exception
*/ */
public void write( int b )
public void write( final int data )
throws IOException throws IOException
{ {
this.oneBuf[ 0 ] = (byte)b;
m_oneBuf[ 0 ] = (byte)data;


this.write( this.oneBuf, 0, 1 );
write( m_oneBuf, 0, 1 );
} }


/** /**
@@ -222,12 +229,11 @@ public class TarOutputStream extends FilterOutputStream
* write( byte[], int, int ). * write( byte[], int, int ).
* *
* @param wBuf The buffer to write to the archive. * @param wBuf The buffer to write to the archive.
* @exception IOException Description of Exception
*/ */
public void write( byte[] wBuf )
public void write( final byte[] buffer )
throws IOException throws IOException
{ {
this.write( wBuf, 0, wBuf.length );
write( buffer, 0, buffer.length );
} }


/** /**
@@ -238,19 +244,22 @@ public class TarOutputStream extends FilterOutputStream
* manages buffers that are not a multiple of recordsize in length, * manages buffers that are not a multiple of recordsize in length,
* including assembling records from small buffers. * 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.
* @exception IOException Description of Exception
* @param buffer The buffer to write to the archive.
* @param offset The offset in the buffer from which to get bytes.
* @param count The number of bytes to write.
*/ */
public void write( byte[] wBuf, int wOffset, int numToWrite )
public void write( final byte[] buffer,
final int offset,
final int count )
throws IOException throws IOException
{ {
if( ( this.currBytes + numToWrite ) > this.currSize )
int position = offset;
int numToWrite = count;
if( ( m_currBytes + numToWrite ) > m_currSize )
{ {
throw new IOException( "request to write '" + numToWrite
+ "' bytes exceeds size in header of '"
+ this.currSize + "' bytes" );
final String message = "request to write '" + numToWrite +
"' bytes exceeds size in header of '" + m_currSize + "' bytes";
throw new IOException( message );
// //
// We have to deal with assembly!!! // We have to deal with assembly!!!
// The programmer can be writing little 32 byte chunks for all // The programmer can be writing little 32 byte chunks for all
@@ -260,30 +269,30 @@ public class TarOutputStream extends FilterOutputStream
// //
} }


if( this.assemLen > 0 )
if( m_assemLen > 0 )
{ {
if( ( this.assemLen + numToWrite ) >= this.recordBuf.length )
if( ( m_assemLen + numToWrite ) >= m_recordBuf.length )
{ {
int aLen = this.recordBuf.length - this.assemLen;
System.arraycopy( this.assemBuf, 0, this.recordBuf, 0,
this.assemLen );
System.arraycopy( wBuf, wOffset, this.recordBuf,
this.assemLen, aLen );
this.buffer.writeRecord( this.recordBuf );
this.currBytes += this.recordBuf.length;
wOffset += aLen;
numToWrite -= aLen;
this.assemLen = 0;
final int length = m_recordBuf.length - m_assemLen;
System.arraycopy( m_assemBuf, 0, m_recordBuf, 0,
m_assemLen );
System.arraycopy( buffer, position, m_recordBuf,
m_assemLen, length );
m_buffer.writeRecord( m_recordBuf );
m_currBytes += m_recordBuf.length;
position += length;
numToWrite -= length;
m_assemLen = 0;
} }
else else
{ {
System.arraycopy( wBuf, wOffset, this.assemBuf, this.assemLen,
System.arraycopy( buffer, position, m_assemBuf, m_assemLen,
numToWrite ); numToWrite );


wOffset += numToWrite;
this.assemLen += numToWrite;
position += numToWrite;
m_assemLen += numToWrite;
numToWrite -= numToWrite; numToWrite -= numToWrite;
} }
} }
@@ -295,41 +304,38 @@ public class TarOutputStream extends FilterOutputStream
// //
while( numToWrite > 0 ) while( numToWrite > 0 )
{ {
if( numToWrite < this.recordBuf.length )
if( numToWrite < m_recordBuf.length )
{ {
System.arraycopy( wBuf, wOffset, this.assemBuf, this.assemLen,
System.arraycopy( buffer, position, m_assemBuf, m_assemLen,
numToWrite ); numToWrite );


this.assemLen += numToWrite;
m_assemLen += numToWrite;


break; break;
} }


this.buffer.writeRecord( wBuf, wOffset );
m_buffer.writeRecord( buffer, position );


int num = this.recordBuf.length;
int num = m_recordBuf.length;


this.currBytes += num;
m_currBytes += num;
numToWrite -= num; numToWrite -= num;
wOffset += num;
position += num;
} }
} }


/** /**
* Write an EOF (end of archive) record to the tar archive. An EOF record * Write an EOF (end of archive) record to the tar archive. An EOF record
* consists of a record of all zeros. * consists of a record of all zeros.
*
* @exception IOException Description of Exception
*/ */
private void writeEOFRecord() private void writeEOFRecord()
throws IOException throws IOException
{ {
for( int i = 0; i < this.recordBuf.length; ++i )
for( int i = 0; i < m_recordBuf.length; ++i )
{ {
this.recordBuf[ i ] = 0;
m_recordBuf[ i ] = 0;
} }


this.buffer.writeRecord( this.recordBuf );
m_buffer.writeRecord( m_recordBuf );
} }
}

}

Loading…
Cancel
Save