private byte [ ] generateARCFileMetaData ( String date ) throws IOException { if ( date != null && date . length ( ) > 14 ) { date = date . substring ( 0 , 14 ) ; } int metadataBodyLength = getMetadataLength ( ) ; // If metadata body, then the minor part of the version is '1' rather // than '0'. String metadataHeaderLinesTwoAndThree = getMetadataHeaderLinesTwoAndThree ( "1 " + ( ( metadataBodyLength > 0 ) ? "1" : "0" ) ) ; int recordLength = metadataBodyLength + metadataHeaderLinesTwoAndThree . getBytes ( DEFAULT_ENCODING ) . length ; String metadataHeaderStr = ARC_MAGIC_NUMBER + getBaseFilename ( ) + " 0.0.0.0 " + date + " text/plain " + recordLength + metadataHeaderLinesTwoAndThree ; ByteArrayOutputStream metabaos = new ByteArrayOutputStream ( recordLength ) ; // Write the metadata header. metabaos . write ( metadataHeaderStr . getBytes ( DEFAULT_ENCODING ) ) ; // Write the metadata body, if anything to write. if ( metadataBodyLength > 0 ) { writeMetaData ( metabaos ) ; } // Write out a LINE_SEPARATORs to end this record. metabaos . write ( LINE_SEPARATOR ) ; // Now get bytes of all just written and compress if flag set. byte [ ] bytes = metabaos . toByteArray ( ) ; if ( isCompressed ( ) ) { // GZIP the header but catch the gzipping into a byte array so we // can add the special IA GZIP header to the product. After // manipulations, write to the output stream (The JAVA GZIP // implementation does not give access to GZIP header. It // produces a 'default' header only). We can get away w/ these // maniupulations because the GZIP 'default' header doesn't // do the 'optional' CRC'ing of the header. byte [ ] gzippedMetaData = ArchiveUtils . gzip ( bytes ) ; if ( gzippedMetaData [ 3 ] != 0 ) { throw new IOException ( "The GZIP FLG header is unexpectedly " + " non-zero. Need to add smarter code that can deal " + " when already extant extra GZIP header fields." ) ; } // Set the GZIP FLG header to '4' which says that the GZIP header // has extra fields. Then insert the alex {'L', 'X', '0', '0', '0, // '0'} 'extra' field. The IA GZIP header will also set byte // 9 (zero-based), the OS byte, to 3 (Unix). We'll do the same. gzippedMetaData [ 3 ] = 4 ; gzippedMetaData [ 9 ] = 3 ; byte [ ] assemblyBuffer = new byte [ gzippedMetaData . length + ARC_GZIP_EXTRA_FIELD . length ] ; // '10' in the below is a pointer past the following bytes of the // GZIP header: ID1 ID2 CM FLG + MTIME(4-bytes) XFL OS. See // RFC1952 for explaination of the abbreviations just used. System . arraycopy ( gzippedMetaData , 0 , assemblyBuffer , 0 , 10 ) ; System . arraycopy ( ARC_GZIP_EXTRA_FIELD , 0 , assemblyBuffer , 10 , ARC_GZIP_EXTRA_FIELD . length ) ; System . arraycopy ( gzippedMetaData , 10 , assemblyBuffer , 10 + ARC_GZIP_EXTRA_FIELD . length , gzippedMetaData . length - 10 ) ; bytes = assemblyBuffer ; } return bytes ; }
Write out the ARCMetaData .