Example #1
0
        /**
         *
         * 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;
        }
Example #3
0
        /*
         * 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);
            }
        }