All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.spardat.xma.pipes.WindowsPipe Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     s IT Solutions AT Spardat GmbH - initial API and implementation
 *******************************************************************************/

/*
 * @(#) $Id: WindowsPipe.java 2089 2007-11-28 13:56:13Z s3460 $
 *
 * 
 * 
 * 
 *
 */
package at.spardat.xma.pipes;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import at.spardat.xma.boot.natives.Pipes;

/**
 * @author s3460
 * @since version_number
 */
public class WindowsPipe extends XMAPipe {

    //private static final String PIPE_PATH = "\\\\.\\pipe\\";
    private static final int BUFFER_SIZE = 4096;    

    private int pipeHandle;

    WindowsPipe(String pipeName) throws IOException {
        //super(PIPE_PATH + pipeName);
        super(pipeName);
        createPipe(getPipeName());
    }

    private void createPipe(String pipeName) throws IOException {
        pipeHandle = Pipes.CreateNamedPipe(pipeName, WIN32Constants.PIPE_ACCESS_DUPLEX, // read/write
                // access
                WIN32Constants.PIPE_TYPE_MESSAGE | // message type
                        // pipe
                        WIN32Constants.PIPE_READMODE_MESSAGE | // message-read
                        // mode
                        WIN32Constants.PIPE_WAIT, // blocking mode
                1,//only one client valid //WIN32Constants.PIPE_UNLIMITED_INSTANCES, // max. instances
                BUFFER_SIZE, // output buffer size
                BUFFER_SIZE, // input buffer size
                WIN32Constants.NMPWAIT_USE_DEFAULT_WAIT, // client time-out
                WIN32Constants.NULL);

        if (pipeHandle == WIN32Constants.INVALID_HANDLE_VALUE) {
            throw new IOException(
                    "Pipe '"
                            + pipeName
                            + "' cannot be created. (WIN-API: CreateNamedPipe()). Windows Error: "
                            + Pipes.FormatMessage(Pipes.GetLastError()));
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see at.spardat.xma.pipes.XMAPipes#destroyPipe()
     */
    public void destroyPipe() throws IOException {
        if (!Pipes.CloseHandle(pipeHandle)) {
            throw new IOException(
                    "Pipe '"
                            + getPipeName()
                            + "' cannot be destroyed. (WIN-API: closeHandel()). Windows Error: "
                            + Pipes.FormatMessage(Pipes.GetLastError()));
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see at.spardat.xma.pipes.XMAPipes#open()
     */
    public void open() throws IOException {
        int error = 0;
        if (!Pipes.ConnectNamedPipe(pipeHandle, WIN32Constants.NULL)
                && (error = Pipes.GetLastError()) != WIN32Constants.ERROR_PIPE_CONNECTED) {
            throw new IOException(
                    "Pipe '"
                            + getPipeName()
                            + "' cannot be opened. (WIN-API: ConnectNamedPipe()). Windows Error: "
                            + Pipes.FormatMessage(error));
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see at.spardat.xma.pipes.XMAPipes#close()
     */
    public void close() throws IOException {
        if (!Pipes.FlushFileBuffers(pipeHandle)) {
        }
        if (!Pipes.DisconnectNamedPipe(pipeHandle)) {
            throw new IOException(
                    "Pipe '"
                            + getPipeName()
                            + "' cannot be closed. (WIN-API: DisconnectNamedPipe()). Windows Error: "
                            + Pipes.FormatMessage(Pipes.GetLastError()));
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see at.spardat.xma.pipes.XMAPipes#write(byte[])
     */
    public void write(byte[] out) throws IOException {
        //Schreibt mehr als BUFFER_SIZE, call kann aber dann blokieren
        //Kann auch durch write Schleife ersetzt werden ! siehe MSDN.
        //Dann blockiert aber die write Funktion. Anforderungen noch unklar...
        //        if (out.length > BUFFER_SIZE) {
        //            throw new IOException("Pipe '" + getPipeName()
        //                    + "' write Error. Byte Array to write lenght (" + out.length
        //                    + ") is greater than max. Buffersize (" + BUFFER_SIZE + ")");
        //        }

        int[] bytesWritten = new int[1];

        if (!Pipes.WriteFile(
                pipeHandle,
                out,
                out.length,
                bytesWritten,
                WIN32Constants.NULL)) {
            throw new IOException(
                    "Pipe '"
                            + getPipeName()
                            + "' write Error. (WIN-API: WriteFile()). Windows Error: "
                            + Pipes.FormatMessage(Pipes.GetLastError()));
        }

        if (out.length != bytesWritten[0]) {
            throw new IOException(
                    "Pipe '"
                            + getPipeName()
                            + "' write Error. (WIN-API: WriteFile()). Byte Array to write lenght ("
                            + out.length + ") actually written bytes (" + bytesWritten[0]
                            + ")");
        }
    }

    /*
     * (non-Javadoc) reads ReadFile in a loop as there can be more data than
     * BUFFER_SIZE
     * 
     * @see at.spardat.xma.pipes.XMAPipes#read()
     */
    public byte[] read() throws IOException {
        ArrayList list = new ArrayList();
        int size = 0;
        //loop as long ReadFile() returns fals end GetLastError() ==
        // ERROR_MORE_DATA
        boolean ok = true;
        int error = 0;
        do {
            byte[] bufferIn = new byte[BUFFER_SIZE];
            int[] bytesRead = new int[1];
            ok = Pipes.ReadFile(
                    pipeHandle,
                    bufferIn,
                    BUFFER_SIZE,
                    bytesRead,
                    WIN32Constants.NULL);
            if (!ok && (error = Pipes.GetLastError()) != WIN32Constants.ERROR_MORE_DATA
                    && error != WIN32Constants.ERROR_SUCCESS) {
                throw new IOException(
                        "Pipe '"
                                + getPipeName()
                                + "' read Error. (WIN-API: ReadFile()). Windows Error: "
                                + Pipes.FormatMessage(error));
            }

            byte[] result = new byte[bytesRead[0]];
            System.arraycopy(bufferIn, 0, result, 0, bytesRead[0]);

            size += bytesRead[0];
            list.add(result);

        } while (!ok);

        //copy all results in one array
        byte[] endresult = new byte[size];
        int i = 0;
        for (Iterator iter = list.iterator(); iter.hasNext();) {
            byte[] element = (byte[]) iter.next();
            System.arraycopy(element, 0, endresult, i, element.length);
            i += element.length;
        }

        return endresult;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy