/** * * Advance the record pointer to the next record. * * @see tinySQLTable#NextRecord * */ public override bool NextRecord() {//throws tinySQLException { // if the record number is greater than zero, // advance the pointer. Otherwise, we're on the first // record, and it hasn't been visited before. // if (record_number > 0) { // try to make it to the next record. An IOException // indicates that we have hit the end of file. // try { ftbl.seek(ftbl.getFilePointer() + record_length + 1); } catch (java.io.IOException) { return(false); } } // increment the record pointer // record_number++; // check for end of file, just in case... // try { if (ftbl.getFilePointer() == ftbl.length()) { return(false); } } catch (Exception e) { throw new TinySQLException(e.getMessage()); } return(true); }
/** * Writes all necessary data for this entry. * @throws IOException on error */ public override void closeArchiveEntry() //throws IOException { if (finished) { throw new java.io.IOException("Stream has already been finished"); } if (entry == null) { throw new java.io.IOException("No current entry to close"); } long realCrc = crc.getValue(); crc.reset(); if (entry.getMethod() == DEFLATED) { def.finish(); while (!def.finished()) { deflate(); } entry.setSize(ZipUtil.adjustToLong(def.getTotalIn())); entry.setCompressedSize(ZipUtil.adjustToLong(def.getTotalOut())); entry.setCrc(realCrc); def.reset(); written += entry.getCompressedSize(); } else if (raf == null) { if (entry.getCrc() != realCrc) { throw new java.util.zip.ZipException("bad CRC checksum for entry " + entry.getName() + ": " + java.lang.Long.toHexString(entry.getCrc()) + " instead of " + java.lang.Long.toHexString(realCrc)); } if (entry.getSize() != written - dataStart) { throw new java.util.zip.ZipException("bad size for entry " + entry.getName() + ": " + entry.getSize() + " instead of " + (written - dataStart)); } } else /* method is STORED and we used RandomAccessFile */ { long size = written - dataStart; entry.setSize(size); entry.setCompressedSize(size); entry.setCrc(realCrc); } // If random access output, write the local file header containing // the correct CRC and compressed/uncompressed sizes if (raf != null) { long save = raf.getFilePointer(); raf.seek(localDataStart); writeOut(ZipLong.getBytes(entry.getCrc())); writeOut(ZipLong.getBytes(entry.getCompressedSize())); writeOut(ZipLong.getBytes(entry.getSize())); raf.seek(save); } writeDataDescriptor(entry); entry = null; }
/* * Find the central directory and read the contents. * * <p>The central directory can be followed by a variable-length comment * field, so we have to scan through it backwards. The comment is at * most 64K, plus we have 18 bytes for the end-of-central-dir stuff * itself, plus apparently sometimes people throw random junk on the end * just for the fun of it.</p> * * <p>This is all a little wobbly. If the wrong value ends up in the EOCD * area, we're hosed. This appears to be the way that everybody handles * it though, so we're in good company if this fails.</p> */ private void readCentralDir() //throws IOException { /* * Scan back, looking for the End Of Central Directory field. If * the archive doesn't have a comment, we'll hit it on the first * try. * * No need to synchronize mRaf here -- we only do this when we * first open the Zip file. */ { long scanOffset = mRaf.length() - ENDHDR; if (scanOffset < 0) { throw new ZipException("too short to be Zip"); } long stopOffset = scanOffset - 65536; if (stopOffset < 0) { stopOffset = 0; } while (true) { mRaf.seek(scanOffset); if (ZipEntry.readIntLE(mRaf) == 101010256L) { break; } scanOffset--; if (scanOffset < stopOffset) { throw new ZipException("EOCD not found; not a Zip archive?"); } } /* * Found it, read the EOCD. * * For performance we want to use buffered I/O when reading the * file. We wrap a buffered stream around the random-access file * object. If we just read from the RandomAccessFile we'll be * doing a read() system call every time. */ RAFStream rafs = new RAFStream(mRaf, mRaf.getFilePointer()); java.io.BufferedInputStream bin = new java.io.BufferedInputStream(rafs, ENDHDR); int diskNumber = ler.readShortLE(bin); int diskWithCentralDir = ler.readShortLE(bin); int numEntries = ler.readShortLE(bin); int totalNumEntries = ler.readShortLE(bin); /*centralDirSize =*/ ler.readIntLE(bin); long centralDirOffset = ler.readIntLE(bin); /*commentLen =*/ ler.readShortLE(bin); if (numEntries != totalNumEntries || diskNumber != 0 || diskWithCentralDir != 0) { throw new ZipException("spanned archives not supported"); } /* * Seek to the first CDE and read all entries. * However, when Z_SYNC_FLUSH is used the offset may not point directly * to the CDE so skip over until we find it. * At most it will be 6 bytes away (one or two bytes for empty block, 4 bytes for * empty block signature). */ scanOffset = centralDirOffset; stopOffset = scanOffset + 6; while (true) { mRaf.seek(scanOffset); if (ZipEntry.readIntLE(mRaf) == CENSIG) { break; } scanOffset++; if (scanOffset > stopOffset) { throw new ZipException("Central Directory Entry not found"); } } // If CDE is found then go and read all the entries rafs = new RAFStream(mRaf, scanOffset); bin = new java.io.BufferedInputStream(rafs, 4096); for (int i = 0; i < numEntries; i++) { ZipEntry newEntry = new ZipEntry(ler, bin); mEntries.put(newEntry.getName(), newEntry); } }