view org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/internal/image/LEDataInputStream.d @ 120:536e43f63c81

Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661 ===D2=== * added [Try]Immutable/Const/Shared templates to work with differenses in D1/D2 instead of version statements used these templates to work with strict type storage rules of dmd-2.053 * com.ibm.icu now also compilable with D2, but not tested yet * small fixes Snippet288 - shared data is in TLS ===Phobos=== * fixed critical bugs in Phobos implemention completely incorrect segfault prone fromStringz (Linux's port ruthless killer) terrible, incorrect StringBuffer realization (StyledText killer) * fixed small bugs as well Snippet72 - misprint in the snippet * implemented missed functionality for Phobos ByteArrayOutputStream implemented (image loading available) formatting correctly works for all DWT's cases As a result, folowing snippets now works with Phobos (Snippet### - what is fixed): Snippet24, 42, 111, 115, 130, 235, 276 - bad string formatting Snippet48, 282 - crash on image loading Snippet163, 189, 211, 213, 217, 218, 222 - crash on copy/cut in StyledText Snippet244 - hang-up ===Tango=== * few changes for the latest Tango trunc-r5661 * few small performance improvments ===General=== * implMissing-s for only one version changed to implMissingInTango/InPhobos * incorrect calls to Format in toString-s fixed * fixed loading \uXXXX characters in ResourceBundle * added good UTF-8 support for StyledText, TextLayout (Win32) and friends UTF functions revised and tested. It is now in java.nonstandard.*Utf modules StyledText and TextLayout (Win32) modules revised for UTF-8 support * removed small diferences in most identical files in *.swt.* folders *.swt.internal.image, *.swt.events and *.swt.custom are identical in Win32/Linux32 now 179 of 576 (~31%) files in *.swt.* folders are fully identical * Win32: snippets now have right subsystem, pretty icons and native system style controls * small fixes in snippets Snippet44 - it's not Snippet44 Snippet212 - functions work with different images and offsets arrays Win32: Snippet282 - crash on close if the button has an image Snippet293 - setGrayed is commented and others Win32: As a result, folowing snippets now works Snippet68 - color doesn't change Snippet163, 189, 211, 213, 217, 218, 222 - UTF-8 issues (see above) Snippet193 - no tabel headers
author Denis Shelomovskij <verylonglogin.reg@gmail.com>
date Sat, 09 Jul 2011 15:50:20 +0300
parents 7a2dd761a8b2
children
line wrap: on
line source

/*******************************************************************************
 * Copyright (c) 2000, 2007 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 * Port to the D programming language:
 *     Frank Benoit <benoit@tionex.de>
 *******************************************************************************/
module org.eclipse.swt.internal.image.LEDataInputStream;


import java.io.InputStream;
import java.lang.all;

final class LEDataInputStream : InputStream{

    alias InputStream.read read;

    InputStream host;

    int position;

    /**
     * The byte array containing the bytes to read.
     */
    protected byte[] buf;

    /**
     * The current position within the byte array <code>buf</code>. A value
     * equal to buf.length indicates no bytes available.  A value of
     * 0 indicates the buffer is full.
     */
    protected int pos;


    public this(InputStream input) {
        this(input, 512);
    }

    public this(InputStream input, int bufferSize) {
        host = input;
        if (bufferSize > 0) {
            buf = new byte[bufferSize];
            pos = bufferSize;
        }
        else throw new IllegalArgumentException("bufferSize must be greater zero" );
    }

    public void close() {
        buf = null;
        if (host !is null) {
            host.close();
            host = null;
        }
    }

    /**
     * Answer how many bytes were read.
     */
    public int getPosition() {
        return position;
    }

    /**
     * Answers how many bytes are available for reading without blocking
     */
    public override int available() {
        if (buf is null) throw new IOException("buf is null");
        return (buf.length - pos) + host.available();
    }

    /**
     * Answer the next byte of the input stream.
     */
    public override int read() {
        if (buf is null) throw new IOException("buf is null");
        if (pos < buf.length) {
            position++;
            return (buf[pos++] & 0xFF);
        }
        int c = host.read();
        if (c !is -1 ) position++;
        return c;
    }

    /**
     * Don't imitate the JDK behaviour of reading a random number
     * of bytes when you can actually read them all.
     */
    public override int read(byte b[], int off, int len) {
        int read = 0, count;
        while (read !is len && (count = readData(b, off, len - read)) !is -1) {
            off += count;
            read += count;
        }
        position += read;
        if (read is 0 && read !is len) return -1;
        return read;
    }

    /**
     * Reads at most <code>length</code> bytes from this LEDataInputStream and
     * stores them in byte array <code>buffer</code> starting at <code>offset</code>.
     * <p>
     * Answer the number of bytes actually read or -1 if no bytes were read and
     * end of stream was encountered.  This implementation reads bytes from
     * the pushback buffer first, then the target stream if more bytes are required
     * to satisfy <code>count</code>.
     * </p>
     * @param buffer the byte array in which to store the read bytes.
     * @param offset the offset in <code>buffer</code> to store the read bytes.
     * @param length the maximum number of bytes to store in <code>buffer</code>.
     *
     * @return int the number of bytes actually read or -1 if end of stream.
     *
     * @exception java.io.IOException if an IOException occurs.
     */
    private int readData(byte[] buffer, int offset, int len) {
        if (buf is null) throw new IOException("buf is null");
        if (offset < 0 || offset > buffer.length ||
            len < 0 || (len > buffer.length - offset)) {
            throw new ArrayIndexOutOfBoundsException(__FILE__,__LINE__);
            }

        int cacheCopied = 0;
        int newOffset = offset;

        // Are there pushback bytes available?
        int available = buf.length - pos;
        if (available > 0) {
            cacheCopied = (available >= len) ? len : available;
            System.arraycopy(buf, pos, buffer, newOffset, cacheCopied);
            newOffset += cacheCopied;
            pos += cacheCopied;
        }

        // Have we copied enough?
        if (cacheCopied is len) return len;

        int inCopied = host.read( buffer, newOffset, len - cacheCopied );
        if( inCopied is -1 ) inCopied = -1;
        if (inCopied > 0 ) return inCopied + cacheCopied;
        if (cacheCopied is 0) return inCopied;
        return cacheCopied;
    }

    /**
     * Answer an integer comprised of the next
     * four bytes of the input stream.
     */
    public int readInt() {
        byte[4] buf = void;
        read(buf);
        return ((buf[3] & 0xFF) << 24) | 
            ((buf[2] & 0xFF) << 16) | 
            ((buf[1] & 0xFF) << 8) | 
            (buf[0] & 0xFF);
    }

    /**
     * Answer a short comprised of the next
     * two bytes of the input stream.
     */
    public short readShort() {
        byte[2] buf = void;
        read(buf);
        return cast(short)(((buf[1] & 0xFF) << 8) | (buf[0] & 0xFF));
    }

    /**
     * Push back the entire content of the given buffer <code>b</code>.
     * <p>
     * The bytes are pushed so that they would be read back b[0], b[1], etc.
     * If the push back buffer cannot handle the bytes copied from <code>b</code>,
     * an IOException will be thrown and no byte will be pushed back.
     * </p>
     *
     * @param b the byte array containing bytes to push back into the stream
     *
     * @exception   java.io.IOException if the pushback buffer is too small
     */
    public void unread(byte[] b) {
        int l = b.length;
        if (l > pos) throw new IOException("cannot unread");
        position -= l;
        pos -= l;
        System.arraycopy(b, 0, buf, pos, l);
    }
}