001/* ----------------------------------------------------------------------------
002   The Kiwi Toolkit - A Java Class Library
003   Copyright (C) 1998-2004 Mark A. Lindner
004
005   This library is free software; you can redistribute it and/or
006   modify it under the terms of the GNU General Public License as
007   published by the Free Software Foundation; either version 2 of the
008   License, or (at your option) any later version.
009
010   This library is distributed in the hope that it will be useful,
011   but WITHOUT ANY WARRANTY; without even the implied warranty of
012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013   General Public License for more details.
014
015   You should have received a copy of the GNU General Public License
016   along with this library; if not, write to the Free Software
017   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018   02111-1307, USA.
019 
020   The author may be contacted at: mark_a_lindner@yahoo.com
021   ----------------------------------------------------------------------------
022   $Log: XDRInputStream.java,v $
023   Revision 1.2  2004/05/05 21:36:35  markl
024   comment block updates
025
026   Revision 1.1  2004/03/16 07:31:25  markl
027   Javadoc added.
028   ----------------------------------------------------------------------------
029*/
030
031package kiwi.io;
032
033import java.io.*;
034
035/**
036 * An input stream for decoding data from the XDR encoding format.
037 *
038 * @author Mark Lindner
039 * @since Kiwi 2.0
040 */
041
042public class XDRInputStream extends FilterInputStream implements XDRDataInput
043  {
044  private static final int UNIT_SIZE = 4;
045  byte unitbuf[] = new byte[UNIT_SIZE], unit2buf[] = new byte[UNIT_SIZE * 2];
046
047  /** Construct a new <code>XDRInputStream</code> that wraps the given
048   * stream.
049   *
050   * @param in The <code>InputStream</code> to wrap.
051   */
052  public XDRInputStream(InputStream in)
053    {
054    super(in);
055    }
056
057  /**
058   */
059  
060  public boolean readBoolean() throws IOException
061    {
062    return(readInt() != 0);
063    }
064
065  /**
066   */
067
068  public char readChar() throws IOException
069    {
070    readFully(unitbuf);
071
072    return((char)(unitbuf[0] & 0xFF));
073    }
074
075  /**
076   */
077  
078  public short readShort() throws IOException
079    {
080    readFully(unitbuf);
081
082    return((short)((unitbuf[0] << 8) | (unitbuf[1] & 0xFF)));
083    }
084
085  /**
086   */
087
088  public int readUnsignedShort() throws IOException
089    {
090    readFully(unitbuf);
091    
092    return(((unitbuf[0] & 0xFF) << 8) | (unitbuf[1] & 0xFF));
093    }
094
095  /**
096   */
097
098  public int readInt() throws IOException
099    {
100    readFully(unitbuf);
101    
102    return(((unitbuf[0] & 0xFF) << 24)
103           | ((unitbuf[1] & 0xFF) << 16)
104           | ((unitbuf[2] & 0xFF) << 8)
105           | (unitbuf[3] & 0xFF));
106    }
107
108  /**
109   */
110
111  public long readUnsignedInt() throws IOException
112    {
113    readFully(unitbuf);
114
115    return((long)((unit2buf[0] & 0xFF) << 24)
116           | (long)((unit2buf[1] & 0xFF) << 16)
117           | (long)((unit2buf[2] & 0xFF) << 8)
118           | (long)((unit2buf[3] & 0xFF)));
119    }
120
121  /**
122   */
123
124  public long readLong() throws IOException
125    { 
126    readFully(unit2buf);
127
128    return((long)((unit2buf[0] & 0xFF) << 56)
129           | (long)((unit2buf[1] & 0xFF) << 48)
130           | (long)((unit2buf[2] & 0xFF) << 40)
131           | (long)((unit2buf[3] & 0xFF) << 36)
132           | (long)((unit2buf[4] & 0xFF) << 24)
133           | (long)((unit2buf[5] & 0xFF) << 16)
134           | (long)((unit2buf[6] & 0xFF) << 8)
135           | (long)((unit2buf[7] & 0xFF)));
136    }
137
138  /**
139   */
140
141  public float readFloat() throws IOException
142    {
143    return(Float.intBitsToFloat(readInt()));
144    }
145
146  /**
147   */
148
149  public double readDouble() throws IOException
150    {
151    return(Double.longBitsToDouble(readLong()));
152    }
153  
154  /*
155   */
156
157  public void readFully(byte[] b) throws IOException
158    {
159    readFully(b, 0, b.length);
160    }
161     
162  /*
163   */
164
165  public void readFully(byte[] b, int offset, int length) throws IOException
166    {
167    while(length > 0)
168      {
169      // in.read will block until some data is available.
170      int r = in.read(b, offset, length);
171      if(r < 0)
172        throw new EOFException();
173      length -= r;
174      offset += r;
175      }
176    }
177
178  /**
179   */
180
181  private void align(int length) throws IOException
182    {
183    int pad = length % UNIT_SIZE;
184    
185    if(pad != 0)
186      readFully(unitbuf, 0, UNIT_SIZE - pad);
187    }
188
189  /**
190   */
191  
192  public String readString(int length) throws IOException
193    {
194    byte[] ascii = new byte[length];
195    readFully(ascii);
196
197    align(length);
198
199    return(new String(ascii)); //BUG: what if default locale is not US-ASCII
200    }
201
202  /**
203   */
204  
205  public String readString() throws IOException
206    {
207    int length = readInt();
208    
209    return(readString(length));
210    }
211  
212  /**
213   */
214  
215  public boolean[] readBooleanArray() throws IOException
216    {
217    int len = readInt();
218    boolean array[] = new boolean[len];
219
220    readBooleanVector(array, 0, len);
221
222    return(array);
223    }
224
225  /**
226   */
227
228  public void readBooleanVector(boolean[] array) throws IOException
229    {
230    readBooleanVector(array, 0, array.length);
231    }
232
233  /**
234   */
235  
236  public void readBooleanVector(boolean[] array, int offset, int length)
237    throws IOException
238    {
239    for(int i = 0; i < length; i++)
240      array[offset++] = readBoolean();
241    }
242
243  /**
244   */
245
246  public byte[] readByteArray() throws IOException
247    {
248    int len = readInt();
249    byte[] array = new byte[len];
250
251    readByteVector(array, 0, len);
252
253    return(array);
254    }
255
256  /**
257   */
258
259  public void readByteVector(byte[] array) throws IOException
260    {
261    readByteVector(array, 0, array.length);
262    }
263
264  /**
265   */
266
267  public void readByteVector(byte[] array, int offset, int length)
268    throws IOException
269    {
270    readFully(array, offset, length);
271
272    align(length);
273    }
274
275  /**
276   */
277
278  public short[] readShortArray() throws IOException
279    {
280    int len = readInt();
281    short[] array = new short[len];
282
283    readShortVector(array, 0, len);
284
285    return(array);
286    }
287
288  /**
289   */
290
291  public void readShortVector(short[] array) throws IOException
292    {
293    readShortVector(array, 0, array.length);
294    }
295
296  /**
297   */
298
299  public void readShortVector(short[] array, int offset, int length)
300    throws IOException
301    {
302    for(int i = 0; i < length; i++)
303      array[offset++] = readShort();
304    }
305
306  /**
307   */
308
309  public int[] readUnsignedShortArray() throws IOException
310    {
311    int len = readInt();
312    int[] array = new int[len];
313
314    readUnsignedShortVector(array, 0, len);
315
316    return(array);
317    }
318
319  /**
320   */
321
322  public void readUnsignedShortVector(int[] array) throws IOException
323    {
324    readUnsignedShortVector(array, 0, array.length);
325    }
326
327  /**
328   */
329
330  public void readUnsignedShortVector(int[] array, int offset, int length)
331    throws IOException
332    {
333    for(int i = 0; i < length; i++)
334      array[offset++] = readUnsignedShort();
335    }
336
337  /**
338   */
339
340  public int[] readIntArray() throws IOException
341    {
342    int len = readInt();
343    int array[] = new int[len];
344
345    readIntVector(array, 0, len);
346
347    return(array);
348    }
349
350  /**
351   */
352
353  public void readIntVector(int[] array) throws IOException
354    {
355    readIntVector(array, 0, array.length);
356    }
357
358  /**
359   */
360
361  public void readIntVector(int[] array, int offset, int length)
362    throws IOException
363    {
364    for(int i = 0; i < length; i++)
365      array[offset++] = readInt();
366    }
367
368  /**
369   */
370
371  public long[] readUnsignedIntArray() throws IOException
372    {
373    int len = readInt();
374    long array[] = new long[len];
375
376    readUnsignedIntVector(array, 0, len);
377
378    return(array);
379    }
380
381  /**
382   */
383
384  public void readUnsignedIntVector(long[] array) throws IOException
385    {
386    readUnsignedIntVector(array, 0, array.length);
387    }
388
389  /**
390   */
391
392  public void readUnsignedIntVector(long[] array, int offset, int length)
393    throws IOException
394    {
395    for(int i = 0; i < length; i++)
396      array[offset++] = readUnsignedInt();
397    }
398
399  /**
400   */
401
402  public long[] readLongArray() throws IOException
403    {
404    int len = readInt();
405    long array[] = new long[len];
406
407    readLongVector(array, 0, len);
408
409    return(array);
410    }
411
412  /**
413   */
414
415  public void readLongVector(long[] array) throws IOException
416    {
417    readLongVector(array, 0, array.length);
418    }
419  
420  /**
421   */
422
423  public void readLongVector(long[] array, int offset, int length)
424    throws IOException
425    {
426    for(int i = 0; i < length; i++)
427      array[offset++] = readLong();
428    }
429
430  /**
431   */
432
433  public float[] readFloatArray() throws IOException
434    {
435    int len = readInt();
436    float array[] = new float[len];
437
438    readFloatVector(array, 0, len);
439
440    return(array);
441    }
442
443  /**
444   */
445
446  public void readFloatVector(float[] array) throws IOException
447    {
448    readFloatVector(array, 0, array.length);
449    }
450
451  /**
452   */
453
454  public void readFloatVector(float[] array, int offset, int length)
455    throws IOException
456    {
457    for(int i = 0; i < length; i++)
458      array[offset++] = readFloat();
459    }
460
461  /**
462   */
463
464  public double[] readDoubleArray() throws IOException
465    {
466    int len = readInt();
467    double array[] = new double[len];
468
469    readDoubleVector(array, 0, len);
470
471    return(array);
472    }
473
474  /**
475   */
476
477  public void readDoubleVector(double[] array) throws IOException
478    {
479    readDoubleVector(array, 0, array.length);
480    }
481
482  /**
483   */
484
485  public void readDoubleVector(double[] array, int offset, int length)
486    throws IOException
487    {
488    for(int i = 0; i < length; i++)
489      array[offset++] = readDouble();
490    }
491  
492  }
493
494/* end of source file */