001    /*
002     * Copyright (c) Andrey Kuznetsov. All Rights Reserved.
003     *
004     * http://uio.imagero.com
005     *
006     * Redistribution and use in source and binary forms, with or without
007     * modification, are permitted provided that the following conditions are met:
008     *
009     *  o Redistributions of source code must retain the above copyright notice,
010     *    this list of conditions and the following disclaimer.
011     *
012     *  o Redistributions in binary form must reproduce the above copyright notice,
013     *    this list of conditions and the following disclaimer in the documentation
014     *    and/or other materials provided with the distribution.
015     *
016     *  o Neither the name of Andrey Kuznetsov nor the names of
017     *    its contributors may be used to endorse or promote products derived
018     *    from this software without specific prior written permission.
019     *
020     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
029     * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
030     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031     */
032    package com.imagero.uio.impl;
033    
034    import com.imagero.uio.ISeekable;
035    import com.imagero.uio.RandomAccessInput;
036    import com.imagero.uio.io.UnexpectedEOFException;
037    import com.imagero.uio.Transformer;
038    
039    import java.io.DataInputStream;
040    import java.io.IOException;
041    import java.io.InputStream;
042    
043    /**
044     * @author Andrey Kuznetsov
045     */
046    public abstract class AbstractRandomAccessInput extends InputStream implements RandomAccessInput {
047        protected int byteOrder = BIG_ENDIAN;
048    
049        public int getByteOrder() {
050            return byteOrder;
051        }
052    
053        public void setByteOrder(int byteOrder) {
054            this.byteOrder = byteOrder;
055        }
056    
057        public boolean isBuffered() {
058            return false;
059        }
060    
061        public final int read(short[] dest) throws IOException {
062            return read(dest, 0, dest.length, byteOrder);
063        }
064    
065        public final int read(short[] dest, int byteOrder) throws IOException {
066            return read(dest, 0, dest.length, byteOrder);
067        }
068    
069        public final int read(short[] dest, int offset, int length) throws IOException {
070            return read(dest, offset, length, byteOrder);
071        }
072    
073        public final int read(char[] dest) throws IOException {
074            return read(dest, 0, dest.length, byteOrder);
075        }
076    
077        public final int read(char[] dest, int byteOrder) throws IOException {
078            return read(dest, 0, dest.length, byteOrder);
079        }
080    
081        public final int read(char[] dest, int offset, int length) throws IOException {
082            return read(dest, offset, length, byteOrder);
083        }
084    
085        public final int read(int[] dest) throws IOException {
086            return read(dest, 0, dest.length, byteOrder);
087        }
088    
089        public final int read(int[] dest, int byteOrder) throws IOException {
090            return read(dest, 0, dest.length, byteOrder);
091        }
092    
093        public final int read(int[] dest, int offset, int length) throws IOException {
094            return read(dest, offset, length, byteOrder);
095        }
096    
097        public final int read(long[] dest) throws IOException {
098            return read(dest, 0, dest.length, byteOrder);
099        }
100    
101        public final int read(long[] dest, int byteOrder) throws IOException {
102            return read(dest, 0, dest.length, byteOrder);
103        }
104    
105        public final int read(long[] dest, int offset, int length) throws IOException {
106            return read(dest, offset, length, byteOrder);
107        }
108    
109        public final int read(float[] dest) throws IOException {
110            return read(dest, 0, dest.length, byteOrder);
111        }
112    
113        public final int read(float[] dest, int byteOrder) throws IOException {
114            return read(dest, 0, dest.length, byteOrder);
115        }
116    
117        public final int read(float[] dest, int offset, int length) throws IOException {
118            return read(dest, offset, length, byteOrder);
119        }
120    
121        public final int read(double[] dest) throws IOException {
122            return read(dest, 0, dest.length, byteOrder);
123        }
124    
125        public final int read(double[] dest, int byteOrder) throws IOException {
126            return read(dest, 0, dest.length, byteOrder);
127        }
128    
129        public final int read(double[] dest, int offset, int length) throws IOException {
130            return read(dest, offset, length, byteOrder);
131        }
132    
133        public final void readFully(short[] dest) throws IOException {
134            readFully(dest, 0, dest.length, byteOrder);
135        }
136    
137        public final void readFully(short[] dest, int byteOrder) throws IOException {
138            readFully(dest, 0, dest.length, byteOrder);
139        }
140    
141        public final void readFully(short[] dest, int destOffset, int len) throws IOException {
142            readFully(dest, 0, dest.length, byteOrder);
143        }
144    
145        public final void readFully(char[] dest) throws IOException {
146            readFully(dest, 0, dest.length, byteOrder);
147        }
148    
149        public final void readFully(char[] dest, int byteOrder) throws IOException {
150            readFully(dest, 0, dest.length, byteOrder);
151        }
152    
153        public final void readFully(char[] dest, int destOffset, int len) throws IOException {
154            readFully(dest, 0, dest.length, byteOrder);
155        }
156    
157        public final void readFully(int[] dest) throws IOException {
158            readFully(dest, 0, dest.length, byteOrder);
159        }
160    
161        public final void readFully(int[] dest, int byteOrder) throws IOException {
162            readFully(dest, 0, dest.length, byteOrder);
163        }
164    
165        public final void readFully(int[] dest, int destOffset, int len) throws IOException {
166            readFully(dest, 0, dest.length, byteOrder);
167        }
168    
169        public final void readFully(long[] dest) throws IOException {
170            readFully(dest, 0, dest.length, byteOrder);
171        }
172    
173        public final void readFully(long[] dest, int byteOrder) throws IOException {
174            readFully(dest, 0, dest.length, byteOrder);
175        }
176    
177        public final void readFully(long[] dest, int destOffset, int len) throws IOException {
178            readFully(dest, 0, dest.length, byteOrder);
179        }
180    
181        public final void readFully(float[] dest) throws IOException {
182            readFully(dest, 0, dest.length, byteOrder);
183        }
184    
185        public final void readFully(float[] dest, int byteOrder) throws IOException {
186            readFully(dest, 0, dest.length, byteOrder);
187        }
188    
189        public final void readFully(float[] dest, int destOffset, int len) throws IOException {
190            readFully(dest, 0, dest.length, byteOrder);
191        }
192    
193        public final void readFully(double[] dest) throws IOException {
194            readFully(dest, 0, dest.length, byteOrder);
195        }
196    
197        public final void readFully(double[] dest, int byteOrder) throws IOException {
198            readFully(dest, 0, dest.length, byteOrder);
199        }
200    
201        public final void readFully(double[] dest, int destOffset, int len) throws IOException {
202            readFully(dest, 0, dest.length, byteOrder);
203        }
204    
205        public final void readFully(short[] dest, int offset, int length, int byteOrder) throws IOException {
206            int sum = 0;
207            while (length > 0) {
208                int read = read(dest, offset, length, byteOrder);
209                if (read <= 0) {
210                    throw new UnexpectedEOFException(sum);
211                }
212                sum += read;
213                length -= read;
214                offset += read;
215            }
216        }
217    
218        public final void readFully(char[] dest, int offset, int length, int byteOrder) throws IOException {
219            int sum = 0;
220            while (length > 0) {
221                int read = read(dest, offset, length, byteOrder);
222                if (read <= 0) {
223                    throw new UnexpectedEOFException(sum);
224                }
225                sum += read;
226                length -= read;
227                offset += read;
228            }
229        }
230    
231        public final void readFully(int[] dest, int offset, int length, int byteOrder) throws IOException {
232            int sum = 0;
233            while (length > 0) {
234                int read = read(dest, offset, length, byteOrder);
235                if (read <= 0) {
236                    throw new UnexpectedEOFException(sum);
237                }
238                sum += read;
239                length -= read;
240                offset += read;
241            }
242        }
243    
244        public final void readFully(long[] dest, int offset, int length, int byteOrder) throws IOException {
245            int sum = 0;
246            while (length > 0) {
247                int read = read(dest, offset, length, byteOrder);
248                if (read <= 0) {
249                    throw new UnexpectedEOFException(sum);
250                }
251                sum += read;
252                length -= read;
253                offset += read;
254            }
255        }
256    
257        public final void readFully(float[] dest, int offset, int length, int byteOrder) throws IOException {
258            int sum = 0;
259            while (length > 0) {
260                int read = read(dest, offset, length, byteOrder);
261                if (read <= 0) {
262                    throw new UnexpectedEOFException(sum);
263                }
264                sum += read;
265                length -= read;
266                offset += read;
267            }
268        }
269    
270        public final void readFully(double[] dest, int offset, int length, int byteOrder) throws IOException {
271            int sum = 0;
272            while (length > 0) {
273                int read = read(dest, offset, length, byteOrder);
274                if (read <= 0) {
275                    throw new UnexpectedEOFException(sum);
276                }
277                sum += read;
278                length -= read;
279                offset += read;
280            }
281        }
282    
283        public final int read(byte[] b) throws IOException {
284            return read(b, 0, b.length);
285        }
286    
287        public final void readFully(byte b[]) throws IOException {
288            readFully(b, 0, b.length);
289        }
290    
291        public int skipBytes(int n) throws IOException {
292            return (int) skip(n);
293        }
294    
295        public final boolean readBoolean() throws IOException {
296            return read() != 0;
297        }
298    
299        public final byte readByte() throws IOException {
300            return (byte) read();
301        }
302    
303        public final int readUnsignedByte() throws IOException {
304            return read();
305        }
306    
307        public final short readShort() throws IOException {
308            return readShort(byteOrder);
309        }
310    
311        public final int readUnsignedShort() throws IOException {
312            return readUnsignedShort(byteOrder);
313        }
314    
315        public final int readUnsignedShort(int byteOrder) throws IOException {
316            byte[] b0 = new byte[2];
317            readFully(b0);
318            return com.imagero.uio.Transformer.byteToShort(b0, 0, byteOrder == BIG_ENDIAN);
319        }
320    
321        public final short readShort(int byteOrder) throws IOException {
322            byte[] b0 = new byte[2];
323            readFully(b0);
324            return (short) com.imagero.uio.Transformer.byteToShort(b0, 0, byteOrder == BIG_ENDIAN);
325        }
326    
327        public final char readChar() throws IOException {
328            return readChar(byteOrder);
329        }
330    
331        public final char readChar(int byteOrder) throws IOException {
332            byte[] b0 = new byte[2];
333            readFully(b0);
334            return (char) com.imagero.uio.Transformer.byteToChar(b0, 0, byteOrder == BIG_ENDIAN);
335        }
336    
337        public final int readInt() throws IOException {
338            return readInt(byteOrder);
339        }
340    
341        public final int readInt(int byteOrder) throws IOException {
342            byte[] b0 = new byte[4];
343            readFully(b0);
344            return com.imagero.uio.Transformer.byteToInt(b0, 0, byteOrder == BIG_ENDIAN);
345        }
346    
347        public final long readLong() throws IOException {
348            return readLong(byteOrder);
349        }
350    
351        public final long readLong(int byteOrder) throws IOException {
352            byte[] b0 = new byte[8];
353            readFully(b0);
354            return com.imagero.uio.Transformer.byteToLong(b0, 0, byteOrder == BIG_ENDIAN);
355        }
356    
357        public final float readFloat() throws IOException {
358            return readFloat(byteOrder);
359        }
360    
361        public final float readFloat(int byteOrder) throws IOException {
362            byte[] b0 = new byte[4];
363            readFully(b0);
364            return com.imagero.uio.Transformer.byteToFloat(b0, 0, byteOrder == BIG_ENDIAN);
365        }
366    
367        public final double readDouble() throws IOException {
368            return readDouble(byteOrder);
369        }
370    
371        public final double readDouble(int byteOrder) throws IOException {
372            byte[] b0 = new byte[8];
373            readFully(b0);
374            return com.imagero.uio.Transformer.byteToDouble(b0, 0, byteOrder == BIG_ENDIAN);
375        }
376    
377        public final String readLine() throws IOException {
378            return new String(readByteLine());
379        }
380    
381        public final String readUTF() throws IOException {
382            return DataInputStream.readUTF(this);
383        }
384    
385        public final byte[] readByteLine() throws IOException {
386            return com.imagero.uio.Transformer.readByteLine(this);
387        }
388    
389        public final int readByteLine(byte[] dest) throws IOException {
390            return com.imagero.uio.Transformer.readByteLine(this, dest);
391        }
392    
393        public int read(short[] dest, int destOffset, int len, int byteOrder) throws IOException {
394            byte[] b = new byte[len * 2];
395            int cnt = read(b);
396    
397            if ((cnt & 1) != 0) {
398                seek(getFilePointer() - 1);
399            }
400            final int count = cnt >> 1;
401            Transformer.byteToShort(b, 0, count, dest, destOffset, byteOrder == ISeekable.BIG_ENDIAN);
402            return count;
403        }
404    
405        public int read(char[] dest, int destOffset, int len, int byteOrder) throws IOException {
406            byte[] b = new byte[len * 2];
407    
408            int cnt = read(b);
409    
410            if ((cnt & 1) != 0) {
411                seek(getFilePointer() - 1);
412            }
413    
414            final int count = cnt >> 1;
415            Transformer.byteToChar(b, 0, count, dest, destOffset, byteOrder == ISeekable.BIG_ENDIAN);
416            return count;
417        }
418    
419        public int read(int[] dest, int destOffset, int len, int byteOrder) throws IOException {
420            byte[] b = new byte[len * 4];
421    
422            int cnt = read(b);
423    
424            int r3 = cnt & 3;
425            if (r3 != 0) {
426                seek(getFilePointer() - r3);
427            }
428    
429            final int count = cnt >> 2;
430            Transformer.byteToInt(b, 0, count, dest, destOffset, byteOrder == ISeekable.BIG_ENDIAN);
431            return count;
432        }
433    
434        public int read(float[] dest, int destOffset, int len, int byteOrder) throws IOException {
435            byte[] b = new byte[len * 4];
436            int cnt = read(b);
437    
438            int r3 = cnt & 3;
439            if (r3 != 0) {
440                seek(getFilePointer() - r3);
441            }
442    
443            final int count = cnt >> 2;
444            Transformer.byteToFloat(b, 0, count, dest, destOffset, byteOrder == ISeekable.BIG_ENDIAN);
445            return count;
446        }
447    
448        public int read(long[] dest, int destOffset, int len, int byteOrder) throws IOException {
449            byte[] b = new byte[len * 8];
450            int cnt = read(b);
451    
452            int r7 = cnt & 7;
453            if (r7 != 0) {
454                seek(getFilePointer() - r7);
455            }
456    
457            final int count = cnt >> 3;
458            Transformer.byteToLong(b, 0, count, dest, destOffset, byteOrder == ISeekable.BIG_ENDIAN);
459            return count;
460        }
461    
462        public int read(double[] dest, int destOffset, int len, int byteOrder) throws IOException {
463            byte[] b = new byte[len * 8];
464            int cnt = read(b);
465    
466            int r7 = cnt & 7;
467            if (r7 != 0) {
468                seek(getFilePointer() - r7);
469            }
470    
471            final int count = cnt >> 3;
472            Transformer.byteToDouble(b, 0, count, dest, destOffset, byteOrder == ISeekable.BIG_ENDIAN);
473            return count;
474        }
475    
476        public void readFully(byte[] b, int off, int len) throws IOException {
477            int n = 0;
478            while (n < len) {
479                int count = read(b, off + n, len - n);
480                if (count < 0) {
481                    throw new UnexpectedEOFException(n);
482                }
483                n += count;
484            }
485        }
486    }