/** * Reads an unsigned integer value from the byte array * {@code buf} at the offset {@code off} * as four bytes, low byte first. * Note that it is <em>not</em> necessary to check the return value with * {@link UInt#check}. * * @param buf The byte array to read the unsigned integer value from. * @param off The zero based offset in the byte array where the first byte * of the unsigned integer value is read from. * @return The unsigned integer value read from the byte array. * Java does not provide {@code unsigned int} as a primitive * type, hence a {@code long} is returned which's four most * significant bytes are zero. */ static long readUInt(final byte[] buf, int off) { return readInt(buf, off) & UInt.MAX_VALUE; }
@Test public void testUShort() { final int s = readUShort(read, 1); assertEquals(0xaa55, s); writeShort(s, write, 1); writeShort(s, write, 3); writeShort(s, write, 5); writeShort(s, write, 7); assertTrue(Arrays.equals(read, write)); }
@Test public void testByte() { final int b1 = readByte(read, 1); final int b2 = readByte(read, 2); assertEquals((byte) 0x55, b1); assertEquals((byte) 0xaa, b2); writeByte(b1, write, 1); writeByte(b2, write, 2); writeByte(b1, write, 3); writeByte(b2, write, 4); writeByte(b1, write, 5); writeByte(b2, write, 6); writeByte(b1, write, 7); writeByte(b2, write, 8); assertTrue(Arrays.equals(read, write)); }
rof.seek(eocdrOff); rof.readFully(sig); if (EOCDR_SIG != readUInt(sig, 0)) continue; rof.readFully(eocdr); int off = 0; diskNo = readUShort(eocdr, off); off += 2; cdDiskNo = readUShort(eocdr, off); off += 2; cdEntriesDisk = readUShort(eocdr, off); off += 2; cdEntries = readUShort(eocdr, off); off += 2; if (0 != diskNo || 0 != cdDiskNo || cdEntriesDisk != cdEntries) throw new ZipException( "ZIP file spanning/splitting is not supported!"); cdSize = readUInt(eocdr, off); off += 4; cdOffset = readUInt(eocdr, off); off += 4; commentLen = readUShort(eocdr, off); final byte[] zip64eocdl = new byte[ZIP64_EOCDL_LEN]; rof.readFully(zip64eocdl); if (ZIP64_EOCDL_SIG != readUInt(zip64eocdl, 0)) { final long totalDisks; // total number of disks
if (CFH_SIG != readUInt(cfh, 0)) break; rof.readFully(cfh, 4, CFH_MIN_LEN - 4); final int gpbf = readUShort(cfh, 8); final int nameLen = readUShort(cfh, 28); final byte[] name = new byte[nameLen]; rof.readFully(name); entry.setRawPlatform(readUShort(cfh, off) >> 8); off += 2; entry.setRawMethod(readUShort(cfh, off)); off += 2; entry.setRawTime(readUInt(cfh, off)); off += 4; entry.setRawCrc(readUInt(cfh, off)); off += 4; entry.setRawCompressedSize(readUInt(cfh, off)); off += 4; entry.setRawSize(readUInt(cfh, off)); off += 4; final int extraLen = readUShort(cfh, off); off += 2;
@Test public void testShort() { final int s = readShort(read, 1); assertEquals((short) 0xaa55, s); writeShort(s, write, 1); writeShort(s, write, 3); writeShort(s, write, 5); writeShort(s, write, 7); assertTrue(Arrays.equals(read, write)); }
@Override void writeTo(byte[] buf, int off) { writeShort(this.vendorVersion, buf, off); off += 2; writeShort(VENDOR_ID, buf, off); off += 2; buf[off] = this.encryptionStrength; off += 1; writeShort(this.method, buf, off); // off += 2; } }
@Override void readFrom(final byte[] buf, int off, final int len) { if (DATA_SIZE != len) throw new IllegalArgumentException(); setVendorVersion(readUShort(buf, off)); off += 2; final int vendorId = (short) readUShort(buf, off); off += 2; if (VENDOR_ID != vendorId) throw new IllegalArgumentException(); setKeyStrength(keyStrength(buf[off])); // checked off += 1; setMethod(readUShort(buf, off)); // off += 2; }
@Test public void testUByte() { final int b1 = readUByte(read, 1); final int b2 = readUByte(read, 2); assertEquals(0x55, b1); assertEquals(0xaa, b2); writeByte(b1, write, 1); writeByte(b2, write, 2); writeByte(b1, write, 3); writeByte(b2, write, 4); writeByte(b1, write, 5); writeByte(b2, write, 6); writeByte(b1, write, 7); writeByte(b2, write, 8); assertTrue(Arrays.equals(read, write)); }
private void checkZipFileSignature(final ReadOnlyFile rof) throws IOException { final byte[] sig = new byte[4]; rof.seek(this.preamble); rof.readFully(sig); final long signature = readUInt(sig, 0); // Constraint: A ZIP file must start with a Local File Header // or a (ZIP64) End Of Central Directory Record iff it's emtpy. if (LFH_SIG != signature && ZIP64_EOCDR_SIG != signature && EOCDR_SIG != signature) throw new ZipException( "Expected Local File Header or (ZIP64) End Of Central Directory Record!"); }
if (UInt.MAX_VALUE <= size) { assert UInt.MAX_VALUE == size; setRawSize(readLong(data, off)); off += 8; if (UInt.MAX_VALUE <= csize) { assert UInt.MAX_VALUE == csize; setRawCompressedSize(readLong(data, off)); off += 8; if (UInt.MAX_VALUE <= offset) { assert UInt.MAX_VALUE == offset; setRawOffset(readLong(data, off));
final byte[] lfh = new byte[LFH_MIN_LEN]; rof.readFully(lfh); if (LFH_SIG != readUInt(lfh, 0)) throw new ZipException("Expected Local File Header!"); final int gpbf = readUShort(lfh, 6); final int nameLen = readUShort(lfh, 26); final byte[] name = new byte[nameLen]; rof.readFully(name); entry.setRawMethod(readUShort(lfh, off)); off += 2; entry.setRawTime(readUInt(lfh, off)); off += 4; entry.setRawCrc(readUInt(lfh, off)); off += 4; entry.setRawCompressedSize(readUInt(lfh, off)); off += 4; entry.setRawSize(readUInt(lfh, off)); off += 4; final int extraLen = readUShort(lfh, off); rof.seek(fp); rof.readFully(dd, 0, 4); long crc = readUInt(dd, 0);
final byte[] lfh = new byte[LFH_MIN_LEN]; rof.readFully(lfh); if (LFH_SIG != readUInt(lfh, 0)) throw new ZipException(name + " (expected Local File Header)"); fp += LFH_MIN_LEN + readUShort(lfh, LFH_FILE_NAME_LENGTH_OFF) // file name length + readUShort(lfh, LFH_FILE_NAME_LENGTH_OFF + 2); // extra field length ReadOnlyFile erof; try { rof.seek(fp + entry.getCompressedSize()); rof.readFully(dd); localCrc = readUInt(dd, 0); if (DD_SIG == localCrc) localCrc = readUInt(dd, 4); } else { localCrc = readUInt(lfh, 14);
/** * Serializes a list of Extra Fields of {@link #getExtraLength} bytes to the * byte array {@code data} at the zero based offset {@code off}. * Upon return, this collection shall not access {@code data} * subsequently. * * @param data The byte array to write the list of Extra Fields to. * @param off The zero based offset in the byte array where the first byte * of the list of Extra Fields is written to. * @throws IndexOutOfBoundsException If the byte array * {@code data} does not hold at least {@link #getExtraLength} * bytes at the zero based offset {@code off}. * @see #getExtraLength */ void writeTo(final byte[] data, int off) throws IndexOutOfBoundsException { for (final ExtraField ef : extra.values()) { writeShort(ef.getHeaderId(), data, off); off += 2; writeShort(ef.getDataSize(), data, off); off += 2; ef.writeTo(data, off); off += ef.getDataSize(); } } }
final int end = off + len; while (off < end) { final int headerId = readUShort(buf, off); off += 2; final int dataSize = readUShort(buf, off); off += 2; final ExtraField ef = ExtraField.create(headerId);