Hello.

I have run into another problem with the Kaffe zip
libs. It looks like the read() method for a ZipInputStream
does not read the correct amount of data from a ZipEntry.
Here is a simple example that shows what kaffe is doing
wrong. I am going to try to figure this one out but if
someone else beats me to the fix I will bear no grudge.




/*
FILE : ZipWrite.java
Writes an uncompressed data stream to a zip file using the java
zip classes.
*/

import java.io.*;
import java.util.zip.*;

public class ZipWrite {

    public static void main(String[] argv) throws Exception {
        String fname = "zip1.zip";

        if ((new File(fname)).exists()) {
            fname = "zip2.zip";
        }
        
        FileOutputStream fos = new FileOutputStream(fname);

        ZipOutputStream zout = new ZipOutputStream(fos);
        
        ZipEntry ze;

        int total = 10;

        byte[] bytes1 = new byte[total];
        byte[] bytes2 = new byte[total];
        byte[] empty  = new byte[0];
        
        for (int i=0; i < total; i++) {
            byte num =(byte)
                (((i+1) > Byte.MAX_VALUE) ? ((i+1) % Byte.MAX_VALUE) : (i+1));
            bytes1[i] = num;
            bytes2[total - i - 1] = num;
        }

        addEntry("data1", bytes1, zout);
        addEntry("data2", bytes2, zout);
        /*
        addEntry("data3", bytes1, zout);
        addEntry("data4", bytes2, zout);
        addEntry("dir1/", empty, zout);
        addEntry("dir1/data5", bytes1, zout);
        */

        zout.close();

        File f = new File(fname);
        System.out.println("Wrote \"" + fname + "\"," +
                           " file size = " + f.length() );
    }



    public static void addEntry(String name, byte[] bytes, ZipOutputStream zout)
        throws Exception
    {
        ZipEntry ze = new ZipEntry(name);

        ze.setMethod(ZipEntry.STORED);
        ze.setSize( bytes.length );
        ze.setCrc( 0 );

        zout.putNextEntry(ze);

        zout.write(bytes);
        
        CRC32 crc = new CRC32();
        crc.update(bytes);      
        ze.setCrc( crc.getValue() );

        zout.closeEntry();

        System.out.println("Wrote \"" + name + "\", data size = " + bytes.length);
    }
}







/*
FILE : ZipExtract.java
Extract classes from a zip archive.
*/


import java.io.*;
import java.util.zip.*;

public class ZipExtract {

    public static void main(String[] argv) throws Exception {
        final boolean debug = true;
        String fname;

        if (argv.length != 1) {
            System.err.println("usage : java ZipExtract zipfile");
            System.exit(-1);
        }

        fname = argv[0];
        
        FileInputStream fis = new FileInputStream(fname);

        ZipInputStream zin = new ZipInputStream(fis);
        
        ZipEntry entry;

        while ((entry = zin.getNextEntry()) != null) {
            String name = entry.getName();

            if (entry.isDirectory()) {
                File dir = new File(name);
                if (! dir.exists()) {
                    if (debug) {
                        System.out.println("making directory \"" + 
                                           dir.getPath() + "\"");
                    }
                    dir.mkdirs();
                }
                continue;
            }
            
            if (debug) {
                System.out.println("opening output file \"" +
                                   name + "\"");
            }
            
            FileOutputStream fos = new FileOutputStream(name);
            
            try {
                readwriteStreams(zin, fos);
            } finally {
                fos.close();
            }
        }

        zin.close();
    }



    // This method is used to transfer the contents of input stream to
    // and output stream. The input stream will be read until EOF is
    // returned by the read() method.

    static void readwriteStreams(InputStream in, OutputStream out)
        throws IOException
    {
        final boolean debug = true;

        int numRead;
        int numWritten = 0;

        byte[] buffer = new byte[8094];


        if (debug) {
            System.out.println("read/write buffer size is " +
                               buffer.length + " bytes");
        }
        
        while ((numRead = in.read(buffer,0,buffer.length)) != -1) {
            if (debug) {
                System.out.println("read " + numRead +
                                   " bytes, writing ...");
            }
            
            out.write(buffer,0,numRead);
            numWritten += numRead;
        }

        if (debug) {
            System.out.println("wrote a total of " + numWritten + " bytes.");
        }
    }

}






% java ZipWrite
Wrote "data1", data size = 10
Wrote "data2", data size = 10
Wrote "zip1.zip", file size = 214




% java ZipExtract zip1.zip 
opening output file "data1"
read/write buffer size is 8094 bytes
read 10 bytes, writing ...
wrote a total of 10 bytes.
opening output file "data2"
read/write buffer size is 8094 bytes
read 10 bytes, writing ...
wrote a total of 10 bytes.



% kaffe ZipExtract zip1.zip
opening output file "data1"
read/write buffer size is 8094 bytes
read 179 bytes, writing ...
wrote a total of 179 bytes.
java.io.IOException: signature not found
        at java.lang.Throwable.<init>(Throwable.java:37)
        at java.lang.Exception.<init>(Exception.java:21)
        at java.io.IOException.<init>(IOException.java:22)
        at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:39)
        at ZipExtract.main(ZipExtract.java:28)



later
Mo DeJong
dejong at cs.umn.edu

Reply via email to