25
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2000, 2007 IBM Corporation and others.
|
|
3 * All rights reserved. This program and the accompanying materials
|
|
4 * are made available under the terms of the Eclipse Public License v1.0
|
|
5 * which accompanies this distribution, and is available at
|
|
6 * http://www.eclipse.org/legal/epl-v10.html
|
|
7 *
|
|
8 * Contributors:
|
|
9 * IBM Corporation - initial API and implementation
|
|
10 * Port to the D programming language:
|
|
11 * Frank Benoit <benoit@tionex.de>
|
|
12 *******************************************************************************/
|
|
13 module org.eclipse.swt.internal.image.LEDataInputStream;
|
|
14
|
|
15 import java.lang.all;
|
|
16
|
|
17
|
|
18 import java.io.InputStream;
|
|
19
|
|
20 final class LEDataInputStream : InputStream{
|
|
21
|
|
22 alias InputStream.read read;
|
|
23
|
|
24 InputStream host;
|
|
25
|
|
26 int position;
|
|
27
|
|
28 /**
|
|
29 * The byte array containing the bytes to read.
|
|
30 */
|
|
31 protected byte[] buf;
|
|
32
|
|
33 /**
|
|
34 * The current position within the byte array <code>buf</code>. A value
|
|
35 * equal to buf.length indicates no bytes available. A value of
|
|
36 * 0 indicates the buffer is full.
|
|
37 */
|
|
38 protected int pos;
|
|
39
|
|
40
|
|
41 public this(InputStream input) {
|
|
42 this(input, 512);
|
|
43 }
|
|
44
|
|
45 public this(InputStream input, int bufferSize) {
|
|
46 host = input;
|
|
47 if (bufferSize > 0) {
|
|
48 buf = new byte[bufferSize];
|
|
49 pos = bufferSize;
|
|
50 }
|
|
51 else throw new IllegalArgumentException("bufferSize must be greater zero" );
|
|
52 }
|
|
53
|
|
54 public void close() {
|
|
55 buf = null;
|
|
56 if (host !is null) {
|
|
57 host.close();
|
|
58 host = null;
|
|
59 }
|
|
60 }
|
|
61
|
|
62 /**
|
|
63 * Answer how many bytes were read.
|
|
64 */
|
|
65 public int getPosition() {
|
|
66 return position;
|
|
67 }
|
|
68
|
|
69 /**
|
|
70 * Answers how many bytes are available for reading without blocking
|
|
71 */
|
|
72 public override int available() {
|
|
73 if (buf is null) throw new IOException("buf is null");
|
|
74 return (buf.length - pos) + host.available();
|
|
75 }
|
|
76
|
|
77 /**
|
|
78 * Answer the next byte of the input stream.
|
|
79 */
|
|
80 public override int read() {
|
|
81 if (buf is null) throw new IOException("buf is null");
|
|
82 if (pos < buf.length) {
|
|
83 position++;
|
|
84 return (buf[pos++] & 0xFF);
|
|
85 }
|
|
86 int c = host.read();
|
|
87 if (c !is -1 ) position++;
|
|
88 return c;
|
|
89 }
|
|
90
|
|
91 /**
|
|
92 * Don't imitate the JDK behaviour of reading a random number
|
|
93 * of bytes when you can actually read them all.
|
|
94 */
|
|
95 public override int read(byte b[], int off, int len) {
|
|
96 int read = 0, count;
|
|
97 while (read !is len && (count = readData(b, off, len - read)) !is -1) {
|
|
98 off += count;
|
|
99 read += count;
|
|
100 }
|
|
101 position += read;
|
|
102 if (read is 0 && read !is len) return -1;
|
|
103 return read;
|
|
104 }
|
|
105
|
|
106 /**
|
|
107 * Reads at most <code>length</code> bytes from this LEDataInputStream and
|
|
108 * stores them in byte array <code>buffer</code> starting at <code>offset</code>.
|
|
109 * <p>
|
|
110 * Answer the number of bytes actually read or -1 if no bytes were read and
|
|
111 * end of stream was encountered. This implementation reads bytes from
|
|
112 * the pushback buffer first, then the target stream if more bytes are required
|
|
113 * to satisfy <code>count</code>.
|
|
114 * </p>
|
|
115 * @param buffer the byte array in which to store the read bytes.
|
|
116 * @param offset the offset in <code>buffer</code> to store the read bytes.
|
|
117 * @param length the maximum number of bytes to store in <code>buffer</code>.
|
|
118 *
|
|
119 * @return int the number of bytes actually read or -1 if end of stream.
|
|
120 *
|
|
121 * @exception java.io.IOException if an IOException occurs.
|
|
122 */
|
|
123 private int readData(byte[] buffer, int offset, int len) {
|
|
124 if (buf is null) throw new IOException("buf is null");
|
|
125 if (offset < 0 || offset > buffer.length ||
|
|
126 len < 0 || (len > buffer.length - offset)) {
|
|
127 throw new ArrayBoundsException(__FILE__,__LINE__);
|
|
128 }
|
|
129
|
|
130 int cacheCopied = 0;
|
|
131 int newOffset = offset;
|
|
132
|
|
133 // Are there pushback bytes available?
|
|
134 int available = buf.length - pos;
|
|
135 if (available > 0) {
|
|
136 cacheCopied = (available >= len) ? len : available;
|
|
137 System.arraycopy(buf, pos, buffer, newOffset, cacheCopied);
|
|
138 newOffset += cacheCopied;
|
|
139 pos += cacheCopied;
|
|
140 }
|
|
141
|
|
142 // Have we copied enough?
|
|
143 if (cacheCopied is len) return len;
|
|
144
|
|
145 int inCopied = host.read( buffer, newOffset, len - cacheCopied );
|
|
146 if( inCopied is -1 ) inCopied = -1;
|
|
147 if (inCopied > 0 ) return inCopied + cacheCopied;
|
|
148 if (cacheCopied is 0) return inCopied;
|
|
149 return cacheCopied;
|
|
150 }
|
|
151
|
|
152 /**
|
|
153 * Answer an integer comprised of the next
|
|
154 * four bytes of the input stream.
|
|
155 */
|
|
156 public int readInt() {
|
|
157 byte[4] buf = void;
|
|
158 read(buf);
|
|
159 return ((buf[3] & 0xFF) << 24) |
|
|
160 ((buf[2] & 0xFF) << 16) |
|
|
161 ((buf[1] & 0xFF) << 8) |
|
|
162 (buf[0] & 0xFF);
|
|
163 }
|
|
164
|
|
165 /**
|
|
166 * Answer a short comprised of the next
|
|
167 * two bytes of the input stream.
|
|
168 */
|
|
169 public short readShort() {
|
|
170 byte[2] buf = void;
|
|
171 read(buf);
|
|
172 return cast(short)(((buf[1] & 0xFF) << 8) | (buf[0] & 0xFF));
|
|
173 }
|
|
174
|
|
175 /**
|
|
176 * Push back the entire content of the given buffer <code>b</code>.
|
|
177 * <p>
|
|
178 * The bytes are pushed so that they would be read back b[0], b[1], etc.
|
|
179 * If the push back buffer cannot handle the bytes copied from <code>b</code>,
|
|
180 * an IOException will be thrown and no byte will be pushed back.
|
|
181 * </p>
|
|
182 *
|
|
183 * @param b the byte array containing bytes to push back into the stream
|
|
184 *
|
|
185 * @exception java.io.IOException if the pushback buffer is too small
|
|
186 */
|
|
187 public void unread(byte[] b) {
|
|
188 int l = b.length;
|
|
189 if (l > pos) throw new IOException("cannot unread");
|
|
190 position -= l;
|
|
191 pos -= l;
|
|
192 System.arraycopy(b, 0, buf, pos, l);
|
|
193 }
|
|
194 }
|