/** * Finishes writing the contents of the CPIO output stream without closing * the underlying stream. Use this method when applying multiple filters in * succession to the same output stream. * * @throws IOException * if an I/O exception has occurred or if a CPIO file error has * occurred */ public override void finish() //throws IOException { ensureOpen(); if (finished) { throw new java.io.IOException("This archive has already been finished"); } if (this.entry != null) { throw new java.io.IOException("This archive contains unclosed entries."); } this.entry = new CpioArchiveEntry(this.entryFormat); this.entry.setName(CpioConstants.CPIO_TRAILER); this.entry.setNumberOfLinks(1); writeHeader(this.entry); closeArchiveEntry(); int lengthOfLastBlock = (int)(getBytesWritten() % blockSize); if (lengthOfLastBlock != 0) { pad(blockSize - lengthOfLastBlock); } finished = true; }
/** * Begins writing a new CPIO file entry and positions the stream to the * start of the entry data. Closes the current entry if still active. The * current time will be used if the entry has no set modification time and * the default header format will be used if no other format is specified in * the entry. * * @param entry * the CPIO cpioEntry to be written * @throws IOException * if an I/O error has occurred or if a CPIO file error has * occurred * @throws ClassCastException if entry is not an instance of CpioArchiveEntry */ public override void putArchiveEntry(ArchiveEntry entry) //throws IOException { if (finished) { throw new java.io.IOException("Stream has already been finished"); } CpioArchiveEntry e = (CpioArchiveEntry)entry; ensureOpen(); if (this.entry != null) { closeArchiveEntry(); // close previous entry } if (e.getTime() == -1) { e.setTime(java.lang.SystemJ.currentTimeMillis() / 1000); } short format = e.getFormat(); if (format != this.entryFormat) { throw new java.io.IOException("Header format: " + format + " does not match existing format: " + this.entryFormat); } if (this.names.put(e.getName(), e) != null) { throw new java.io.IOException("duplicate entry: " + e.getName()); } writeHeader(e); this.entry = e; this.written = 0; }
/*(non-Javadoc) * * @see * org.apache.commons.compress.archivers.ArchiveOutputStream#closeArchiveEntry * () */ public override void closeArchiveEntry() //throws IOException { if (finished) { throw new java.io.IOException("Stream has already been finished"); } ensureOpen(); if (entry == null) { throw new java.io.IOException("Trying to close non-existent entry"); } if (this.entry.getSize() != this.written) { throw new java.io.IOException("invalid entry size (expected " + this.entry.getSize() + " but got " + this.written + " bytes)"); } pad(this.entry.getDataPadCount()); if (this.entry.getFormat() == CpioConstants.FORMAT_NEW_CRC) { if (this.crc != this.entry.getChksum()) { throw new java.io.IOException("CRC Error"); } } this.entry = null; this.crc = 0; this.written = 0; }
private void writeHeader(CpioArchiveEntry e) //throws IOException { switch (e.getFormat()) { case CpioConstants.FORMAT_NEW: outJ.write(ArchiveUtils.toAsciiBytes(CpioConstants.MAGIC_NEW)); count(6); writeNewEntry(e); break; case CpioConstants.FORMAT_NEW_CRC: outJ.write(ArchiveUtils.toAsciiBytes(CpioConstants.MAGIC_NEW_CRC)); count(6); writeNewEntry(e); break; case CpioConstants.FORMAT_OLD_ASCII: outJ.write(ArchiveUtils.toAsciiBytes(CpioConstants.MAGIC_OLD_ASCII)); count(6); writeOldAsciiEntry(e); break; case CpioConstants.FORMAT_OLD_BINARY: bool swapHalfWord = true; writeBinaryLong(CpioConstants.MAGIC_OLD_BINARY, 2, swapHalfWord); writeOldBinaryEntry(e, swapHalfWord); break; } }
/* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ public override bool Equals(Object obj) { if (this == obj) { return(true); } if (obj == null || this.GetType() != obj.GetType()) { return(false); } CpioArchiveEntry other = (CpioArchiveEntry)obj; if (name == null) { if (other.name != null) { return(false); } } else if (!name.equals(other.name)) { return(false); } return(true); }
private CpioArchiveEntry readOldBinaryEntry(bool swapHalfWord) // throws IOException { CpioArchiveEntry ret = new CpioArchiveEntry(CpioConstants.FORMAT_OLD_BINARY); ret.setDevice(readBinaryLong(2, swapHalfWord)); ret.setInode(readBinaryLong(2, swapHalfWord)); long mode = readBinaryLong(2, swapHalfWord); if (mode != 0) { ret.setMode(mode); } ret.setUID(readBinaryLong(2, swapHalfWord)); ret.setGID(readBinaryLong(2, swapHalfWord)); ret.setNumberOfLinks(readBinaryLong(2, swapHalfWord)); ret.setRemoteDevice(readBinaryLong(2, swapHalfWord)); ret.setTime(readBinaryLong(4, swapHalfWord)); long namesize = readBinaryLong(2, swapHalfWord); ret.setSize(readBinaryLong(4, swapHalfWord)); String name = readCString((int)namesize); ret.setName(name); if (mode == 0 && !name.equals(CpioConstants.CPIO_TRAILER)) { throw new java.io.IOException("Mode 0 only allowed in the trailer. Found entry: " + name + "Occured at byte: " + getBytesRead()); } skip(ret.getHeaderPadCount()); return(ret); }
private CpioArchiveEntry readOldAsciiEntry() //throws IOException { CpioArchiveEntry ret = new CpioArchiveEntry(CpioConstants.FORMAT_OLD_ASCII); ret.setDevice(readAsciiLong(6, 8)); ret.setInode(readAsciiLong(6, 8)); long mode = readAsciiLong(6, 8); if (mode != 0) { ret.setMode(mode); } ret.setUID(readAsciiLong(6, 8)); ret.setGID(readAsciiLong(6, 8)); ret.setNumberOfLinks(readAsciiLong(6, 8)); ret.setRemoteDevice(readAsciiLong(6, 8)); ret.setTime(readAsciiLong(11, 8)); long namesize = readAsciiLong(6, 8); ret.setSize(readAsciiLong(11, 8)); String name = readCString((int)namesize); ret.setName(name); if (mode == 0 && !name.equals(CpioConstants.CPIO_TRAILER)) { throw new java.io.IOException("Mode 0 only allowed in the trailer. Found entry: " + name + " Occured at byte: " + getBytesRead()); } return(ret); }
/** * Reads the next CPIO file entry and positions stream at the beginning of * the entry data. * * @return the CPIOArchiveEntry just read * @throws IOException * if an I/O error has occurred or if a CPIO file error has * occurred */ public CpioArchiveEntry getNextCPIOEntry() //throws IOException { ensureOpen(); if (this.entry != null) { closeEntry(); } byte [] magic = new byte[2]; readFully(magic, 0, magic.Length); if (CpioUtil.byteArray2long(magic, false) == CpioConstants.MAGIC_OLD_BINARY) { this.entry = readOldBinaryEntry(false); } else if (CpioUtil.byteArray2long(magic, true) == CpioConstants.MAGIC_OLD_BINARY) { this.entry = readOldBinaryEntry(true); } else { byte [] more_magic = new byte[4]; readFully(more_magic, 0, more_magic.Length); byte [] tmp = new byte[6]; java.lang.SystemJ.arraycopy(magic, 0, tmp, 0, magic.Length); java.lang.SystemJ.arraycopy(more_magic, 0, tmp, magic.Length, more_magic.Length); String magicString = ArchiveUtils.toAsciiString(tmp); if (magicString.equals(CpioConstants.MAGIC_NEW)) { this.entry = readNewEntry(false); } else if (magicString.equals(CpioConstants.MAGIC_NEW_CRC)) { this.entry = readNewEntry(true); } else if (magicString.equals(CpioConstants.MAGIC_OLD_ASCII)) { this.entry = readOldAsciiEntry(); } else { throw new java.io.IOException("Unknown magic [" + magicString + "]. Occured at byte: " + getBytesRead()); } } this.entryBytesRead = 0; this.entryEOF = false; this.crc = 0; if (this.entry.getName().equals(CpioConstants.CPIO_TRAILER)) { this.entryEOF = true; return(null); } return(this.entry); }
private CpioArchiveEntry readNewEntry(bool hasCrc) // throws IOException { CpioArchiveEntry ret; if (hasCrc) { ret = new CpioArchiveEntry(CpioConstants.FORMAT_NEW_CRC); } else { ret = new CpioArchiveEntry(CpioConstants.FORMAT_NEW); } ret.setInode(readAsciiLong(8, 16)); long mode = readAsciiLong(8, 16); if (mode != 0) // mode is initialised to 0 { ret.setMode(mode); } ret.setUID(readAsciiLong(8, 16)); ret.setGID(readAsciiLong(8, 16)); ret.setNumberOfLinks(readAsciiLong(8, 16)); ret.setTime(readAsciiLong(8, 16)); ret.setSize(readAsciiLong(8, 16)); ret.setDeviceMaj(readAsciiLong(8, 16)); ret.setDeviceMin(readAsciiLong(8, 16)); ret.setRemoteDeviceMaj(readAsciiLong(8, 16)); ret.setRemoteDeviceMin(readAsciiLong(8, 16)); long namesize = readAsciiLong(8, 16); ret.setChksum(readAsciiLong(8, 16)); String name = readCString((int)namesize); ret.setName(name); if (mode == 0 && !name.equals(CpioConstants.CPIO_TRAILER)) { throw new java.io.IOException("Mode 0 only allowed in the trailer. Found entry name: " + name + " Occured at byte: " + getBytesRead()); } skip(ret.getHeaderPadCount()); return(ret); }
private void writeNewEntry(CpioArchiveEntry entry) //throws IOException { long inode = entry.getInode(); long devMin = entry.getDeviceMin(); if (CpioConstants.CPIO_TRAILER.equals(entry.getName())) { inode = devMin = 0; } else { if (inode == 0 && devMin == 0) { inode = nextArtificalDeviceAndInode & 0xFFFFFFFF; devMin = (nextArtificalDeviceAndInode++ >> 32) & 0xFFFFFFFF; } else { nextArtificalDeviceAndInode = java.lang.Math.max(nextArtificalDeviceAndInode, inode + 0x100000000L * devMin) + 1; } } writeAsciiLong(inode, 8, 16); writeAsciiLong(entry.getMode(), 8, 16); writeAsciiLong(entry.getUID(), 8, 16); writeAsciiLong(entry.getGID(), 8, 16); writeAsciiLong(entry.getNumberOfLinks(), 8, 16); writeAsciiLong(entry.getTime(), 8, 16); writeAsciiLong(entry.getSize(), 8, 16); writeAsciiLong(entry.getDeviceMaj(), 8, 16); writeAsciiLong(devMin, 8, 16); writeAsciiLong(entry.getRemoteDeviceMaj(), 8, 16); writeAsciiLong(entry.getRemoteDeviceMin(), 8, 16); writeAsciiLong(entry.getName().length() + 1, 8, 16); writeAsciiLong(entry.getChksum(), 8, 16); writeCString(entry.getName()); pad(entry.getHeaderPadCount()); }
private void writeOldBinaryEntry(CpioArchiveEntry entry, bool swapHalfWord) //throws IOException { long inode = entry.getInode(); long device = entry.getDevice(); if (CpioConstants.CPIO_TRAILER.equals(entry.getName())) { inode = device = 0; } else { if (inode == 0 && device == 0) { inode = nextArtificalDeviceAndInode & 0xFFFF; device = (nextArtificalDeviceAndInode++ >> 16) & 0xFFFF; } else { nextArtificalDeviceAndInode = java.lang.Math.max(nextArtificalDeviceAndInode, inode + 0x10000 * device) + 1; } } writeBinaryLong(device, 2, swapHalfWord); writeBinaryLong(inode, 2, swapHalfWord); writeBinaryLong(entry.getMode(), 2, swapHalfWord); writeBinaryLong(entry.getUID(), 2, swapHalfWord); writeBinaryLong(entry.getGID(), 2, swapHalfWord); writeBinaryLong(entry.getNumberOfLinks(), 2, swapHalfWord); writeBinaryLong(entry.getRemoteDevice(), 2, swapHalfWord); writeBinaryLong(entry.getTime(), 4, swapHalfWord); writeBinaryLong(entry.getName().length() + 1, 2, swapHalfWord); writeBinaryLong(entry.getSize(), 4, swapHalfWord); writeCString(entry.getName()); pad(entry.getHeaderPadCount()); }
private void writeOldAsciiEntry(CpioArchiveEntry entry) //throws IOException { long inode = entry.getInode(); long device = entry.getDevice(); if (CpioConstants.CPIO_TRAILER.equals(entry.getName())) { inode = device = 0; } else { if (inode == 0 && device == 0) { inode = nextArtificalDeviceAndInode & 0777777; device = (nextArtificalDeviceAndInode++ >> 18) & 0777777; } else { nextArtificalDeviceAndInode = java.lang.Math.max(nextArtificalDeviceAndInode, inode + 01000000 * device) + 1; } } writeAsciiLong(device, 6, 8); writeAsciiLong(inode, 6, 8); writeAsciiLong(entry.getMode(), 6, 8); writeAsciiLong(entry.getUID(), 6, 8); writeAsciiLong(entry.getGID(), 6, 8); writeAsciiLong(entry.getNumberOfLinks(), 6, 8); writeAsciiLong(entry.getRemoteDevice(), 6, 8); writeAsciiLong(entry.getTime(), 11, 8); writeAsciiLong(entry.getName().length() + 1, 6, 8); writeAsciiLong(entry.getSize(), 11, 8); writeCString(entry.getName()); }