CIB merge technischer Leitfaden

11. Schneller Einstieg

Dieses Kapitel zeigt Ihnen in einem Kurzüberblick eine mögliche Nutzung von CIB merge aus einer Kundenanwendung. Die Beispiele nutzen keineswegs den vollen Funktionsumfang, sondern demonstrieren das grundsätzliche Prinzip beim Umgang mit CIB merge.

Für Ihren konkreten Anwendungsfall können Sie auch gerne beim CIB Support nach weiteren Beispielen rückfragen.


Hinweis:

Zur schnellen Benutzung von CIB merge über die CIB runshell aus der Kommandozeile, befinden sich im Übergabe-Paket fertige Beispiele. Die Aufrufe der CIB runshell sind in Batch-Dateien fertig vorgegeben.


Einbindung von CIB merge als C++ Codebeispiel

Im Kapitel Anwendungsbeispiele sind bereits Codebeispiele vorhanden, die demonstrieren, wie CIB merge aus C++ heraus aufgerufen werden kann. Ein Beispiel zeigt den Aufruf von CIB merge mit Übergabe von mehreren einzelnen Parametern und ein weiteres Beispiel verwendet eine Parameterdatei.

Wenn Sie CIB merge direkt in ihr C++ Programm einbinden möchten, stellt Ihnen der CIB Support gerne ein Beispiel bereit“.


Einbindung von CIB merge als Java Codebeispiel

Im Kapitel Anwendungsbeispiele sind bereits Codebeispiele vorhanden, die demonstrieren, wie CIB merge aus JAVA heraus aufgerufen werden kann. Ein Beispiel zeigt den Aufruf von CIB merge mit Übergabe von mehreren einzelnen Parametern und ein weiteres Beispiel verwendet eine Parameterdatei.

Wenn Sie CIB merge direkt in ihr C++ Programm einbinden möchten, stellt Ihnen der CIB Support gerne ein Beispiel bereit“.


Einbindung von CIB merge als VB Codebeispiel

Wenn Sie CIB merge direkt in ihr VB-Programm einbinden möchten, stellt Ihnen der CIB Support gerne ein Beispiel bereit“.


Einbindung von CIB merge als Delphi Codebeispiel

Wenn Sie CIB merge direkt in ihr Delphi-Programm einbinden möchten, stellt Ihnen der CIB Support gerne ein Beispiel bereit“.


Hinweis zu GZIP unter JAVA

CIB merge ermöglicht mit –z eine ZLIB Komprimierung mit Mehrfachheadern. Unter JAVA ist es nicht möglich solche Dateien mit der GZIP Klasse sofort zu entpacken.

Deshalb unten aufgeführter Beispielcode, der das unterstützt:

/*
 * Created on 01.08.2006
 * <p>
 * It was not possible to take the FilterInputStream as a base class because I
 * had to call super(gzin) in the constructor. This is supposed to be the first
 * line but there gzin is not initialized yet. Further is was not possible to
 * call super(new ExtendedGZIPInputStream(...)) because the nested class cannot
 * access the not then initialized enclosing class.
 * </p>
 */
package de.cib.java.util.zip;
 
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.zip.GZIPInputStream;
 
/**
 * <p>
 * This is a GZIPInputStream capable of reading a gzipped input stream
 * consisting of multiple members.
 * </p>
 * <p>
 * See RFC 1952 about gzip and multiple members.
 * </p>
 * <p>
 * This implementation is based upon the java.io.GZIPInputStream which is not
 * capable of reading further than the first member. For further information on
 * the implementation see the comment for the java file.
 * </p>
 *
 * @author CIB consulting GmbH, Tammo Wüsthoff
 */
public class MultipleMemberGZIPInputStream extends InputStream {
 
    /**
     * I need some data which is not public. So I have to subclass.
     *
     * @author Tammo
     */
   protected class ExtendedGZIPInputStream extends GZIPInputStream {
 
        /**
* Uses a default buffer size     *          * @param in         *            gzipped input stream         * @throws IOException         */        protected ExtendedGZIPInputStream(InputStream in) throws IOException {            super(in);
        } 
        /**         * @param in         *            gzipped input stream         * @param size         *            buffer size         * @throws java.io.IOException         */        public ExtendedGZIPInputStream(InputStream in, int size)                throws IOException {            super(in, size);
        }         /**        * @return a new InputStream with the unprocessed bytes only or null if         *         there were none         */        public InputStream createInputStreamForUnprocessedBytes() {            final int n = getRemaining();            if (n > 0) {                return new ByteArrayInputStream(buf, len - n, n);            }            return null;
        } 
        /**         * @return number of unprocessed bytes         */        public int getRemaining() {            return inf == null ? 0 : inf.getRemaining();
        } 
        /**         * @return true iff there is unprocessed data         */        public boolean hasRemaining() {            return getRemaining() > 0;
        }
    }
 
    /**
     * Unfortunately the trailer is checked in the unprocessed part of the
     * buffer inside the original GZIPInputStream. Well, if I want to continue
     * with the unprocessed data then I have to skip the trailer again. The
     * readTrailer() is private. So I have to guess the length. But the 8 bytes
     * are part of the specification RFC 1952.
     */    protected static final int trailerLength = 8;
 
    /**
     * gzipped input stream maybe with prepended unprocessed data
     */     protected InputStream base;
 
    /**
     * from time to time newly constructed input stream (once per gzip member)
     */    protected ExtendedGZIPInputStream gzin;
 
    /**
     * buffer size if given, -1 else, used for reconstruction of the member gzip
     */    private final int size;
 
    /**
     * Uses a default buffer size
     *
     * @param in     *            gzipped input stream
     * @throws IOException
     */    public MultipleMemberGZIPInputStream(InputStream in) throws IOException {        super();        base = in;
size = -1;        gzin = new ExtendedGZIPInputStream(in);
    }
 
    /**
     * @param in     *            gzipped input stream
     * @param size     *            buffer size
     * @throws IOException
     */
    public MultipleMemberGZIPInputStream(InputStream in, int size)
            throws IOException {
        super();
        base = in;
        this.size = size;
        gzin = new ExtendedGZIPInputStream(in, size);
    }
 
    /**
     * @see java.io.InputStream#available()
     */    public int available() throws IOException {        if (gzin.available() > 0 || base.available() > 0 || gzin.hasRemaining())            return 1;        return 0;
    }
 
    /**
     * @see java.io.InputStream#close()
     */    public void close() throws IOException {        gzin.close();
    }
 
    /**
     * @see java.io.InputStream#mark(int)
     */    public synchronized void mark(int readlimit) {        gzin.mark(readlimit);
    }
 
    /**
     * @see java.io.InputStream#markSupported()
     */    public boolean markSupported() {        return gzin.markSupported();
    }
 
    /**
     * read a single byte retrying if a gzip member ends just here
     *
     * @see java.io.InputStream#read()
     */
   public int read() throws IOException {        int value;        do {            value = gzin.read();
        } while (value == -1 && retry());        return value;
    }
 
    /**
     * @see java.io.InputStream#read(byte[])
     */
    public int read(byte[] b) throws IOException {        return read(b, 0, b.length);
    }
 
    /**
     * read a sequence of bytes retrying if a gzip member ends just here
     *
     * @see java.io.InputStream#read(byte[], int, int)
     */    public int read(byte[] b, int off, int len) throws IOException {        int n;        do {            n = gzin.read(b, off, len);
        } while (n == -1 && retry());        return n;
    }
 
    /**
     * @see java.io.InputStream#reset()
     */    public synchronized void reset() throws IOException {        gzin.reset();
    }
 
    /**
     * If unprocessed input is available then prepend the remaining bytes to the
     * input and skip the trailer. If no unprocessed input is available or after
     * skipping the trailer look if there are more bytes in the input. If yes
     * then make a new gzip input.
     *
     * @return true iff further data available
     * @throws IOException
     */
    protected boolean retry() throws IOException {        InputStream unprocessed = gzin.createInputStreamForUnprocessedBytes();        if (unprocessed != null) {
            base = new SequenceInputStream(unprocessed, base);            base.skip(Math.min(trailerLength, gzin.getRemaining()));
        }
        // well, looking if there are more bytes using available fails for
// several reasons; other solution: try to initialize gzin; this should        // read the gzip header or give eof        try {            if (size == -1) {                gzin = new ExtendedGZIPInputStream(base);            } else {                gzin = new ExtendedGZIPInputStream(base, size);            }
        } catch (EOFException e) {            return false;
        }        return true;
    }
 
    /**
     * @see java.io.InputStream#skip(long)
     */    public long skip(long n) throws IOException {        return gzin.skip(n);
    }
}
 
    private static void testGunzip() {
        try {
            FileInputStream fin = new FileInputStream(                    "d:\\cib\\temp\\output.rtf");
            MultipleMemberGZIPInputStream gzin = new MultipleMemberGZIPInputStream(
                    fin);
            StringBuffer stringbuffer = new StringBuffer();
            final int size = 512;
            byte[] bytebuffer = new byte[size];
            char[] charbuffer = new char[size * 4];
            int read;
            while ((read = gzin.read(bytebuffer)) != -1) {
                int converted = ByteToCharConverter.getDefault().convert(
                        bytebuffer, 0, read, charbuffer, 0, charbuffer.length);
                stringbuffer.append(charbuffer, 0, converted);
            }
            String output = stringbuffer.toString();
            System.out.println(output);
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }