View Javadoc
1   package nl.tudelft.simulation.dsol.animation.gis.io;
2   
3   import java.io.DataInput;
4   import java.io.DataInputStream;
5   import java.io.IOException;
6   import java.io.InputStream;
7   
8   /**
9    * This class enables the object inputstream to be switched from big endian (default in Java) to little endian. The class works
10   * exactly like an ObjectInputStream.
11   * <p>
12   * Copyright (c) 2020-2023 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
13   * for project information <a href="https://simulation.tudelft.nl/dsol/manual/" target="_blank">DSOL Manual</a>. The DSOL
14   * project is distributed under a three-clause BSD-style license, which can be found at
15   * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">DSOL License</a>.
16   * </p>
17   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
18   */
19  public class ObjectEndianInputStream implements DataInput
20  {
21      /** the datainput stream. */
22      private DataInputStream dataInputStream;
23  
24      /** the inputStream. */
25      private InputStream inputStream;
26  
27      /** an 8byte buffer. */
28      private byte[] buffer = new byte[8];
29  
30      /** the code. */
31      private Endianness endianness = Endianness.BIG_ENDIAN;
32  
33      /**
34       * constructs a new ObjectEndianInputStream.
35       * @param inputStream InputStream; the inputStream to use
36       */
37      public ObjectEndianInputStream(final InputStream inputStream)
38      {
39          this.inputStream = inputStream;
40          this.dataInputStream = new DataInputStream(inputStream);
41      }
42  
43      /** {@inheritDoc} */
44      @Override
45      public short readShort() throws IOException
46      {
47          if (this.endianness.equals(Endianness.BIG_ENDIAN))
48          {
49              return this.dataInputStream.readShort();
50          }
51          this.dataInputStream.readFully(this.buffer, 0, 2);
52          return (short) ((this.buffer[1] & 0xff) << 8 | (this.buffer[0] & 0xff));
53      }
54  
55      /** {@inheritDoc} */
56      @Override
57      public int readUnsignedShort() throws IOException
58      {
59          if (this.endianness.equals(Endianness.BIG_ENDIAN))
60          {
61              return this.dataInputStream.readUnsignedShort();
62          }
63          this.dataInputStream.readFully(this.buffer, 0, 2);
64          return ((this.buffer[1] & 0xff) << 8 | (this.buffer[0] & 0xff));
65      }
66  
67      /** {@inheritDoc} */
68      @Override
69      public char readChar() throws IOException
70      {
71          if (this.endianness.equals(Endianness.BIG_ENDIAN))
72          {
73              return this.dataInputStream.readChar();
74          }
75          this.dataInputStream.readFully(this.buffer, 0, 2);
76          return (char) ((this.buffer[1] & 0xff) << 8 | (this.buffer[0] & 0xff));
77      }
78  
79      /** {@inheritDoc} */
80      @Override
81      public int readInt() throws IOException
82      {
83          if (this.endianness.equals(Endianness.BIG_ENDIAN))
84          {
85              return this.dataInputStream.readInt();
86          }
87          this.dataInputStream.readFully(this.buffer, 0, 4);
88          return (this.buffer[3]) << 24 | (this.buffer[2] & 0xff) << 16 | (this.buffer[1] & 0xff) << 8 | (this.buffer[0] & 0xff);
89      }
90  
91      /** {@inheritDoc} */
92      @Override
93      public long readLong() throws IOException
94      {
95          if (this.endianness.equals(Endianness.BIG_ENDIAN))
96          {
97              return this.dataInputStream.readLong();
98          }
99          this.dataInputStream.readFully(this.buffer, 0, 8);
100         return (long) (this.buffer[7]) << 56 | (long) (this.buffer[6] & 0xff) << 48 | (long) (this.buffer[5] & 0xff) << 40
101                 | (long) (this.buffer[4] & 0xff) << 32 | (long) (this.buffer[3] & 0xff) << 24
102                 | (long) (this.buffer[2] & 0xff) << 16 | (long) (this.buffer[1] & 0xff) << 8 | (this.buffer[0] & 0xff);
103     }
104 
105     /** {@inheritDoc} */
106     @Override
107     public float readFloat() throws IOException
108     {
109         if (this.endianness.equals(Endianness.BIG_ENDIAN))
110         {
111             return this.dataInputStream.readFloat();
112         }
113         return Float.intBitsToFloat(readInt());
114     }
115 
116     /** {@inheritDoc} */
117     @Override
118     public double readDouble() throws IOException
119     {
120         if (this.endianness.equals(Endianness.BIG_ENDIAN))
121         {
122             return this.dataInputStream.readDouble();
123         }
124         return Double.longBitsToDouble(readLong());
125     }
126 
127     /**
128      * reads b from the stream.
129      * @param b byte[]; byte
130      * @return in the value
131      * @throws IOException on failure
132      */
133     public int read(final byte[] b) throws IOException
134     {
135         return this.inputStream.read(b);
136     }
137 
138     /**
139      * reads b from the stream.
140      * @param b byte[]; byte
141      * @param off int; offset
142      * @param len int; length
143      * @return in the value
144      * @throws IOException on failure
145      */
146     public int read(final byte[] b, final int off, final int len) throws IOException
147     {
148         return this.inputStream.read(b, off, len);
149     }
150 
151     /** {@inheritDoc} */
152     @Override
153     public void readFully(final byte[] b) throws IOException
154     {
155         this.dataInputStream.readFully(b, 0, b.length);
156     }
157 
158     /** {@inheritDoc} */
159     @Override
160     public void readFully(final byte[] b, final int off, final int len) throws IOException
161     {
162         this.dataInputStream.readFully(b, off, len);
163     }
164 
165     /** {@inheritDoc} */
166     @Override
167     public int skipBytes(final int n) throws IOException
168     {
169         return this.dataInputStream.skipBytes(n);
170     }
171 
172     /** {@inheritDoc} */
173     @Override
174     public boolean readBoolean() throws IOException
175     {
176         return this.dataInputStream.readBoolean();
177     }
178 
179     /** {@inheritDoc} */
180     @Override
181     public byte readByte() throws IOException
182     {
183         return this.dataInputStream.readByte();
184     }
185 
186     /** {@inheritDoc} */
187     @Override
188     public int readUnsignedByte() throws IOException
189     {
190         return this.dataInputStream.readUnsignedByte();
191     }
192 
193     /** {@inheritDoc} */
194     @Override
195     public String readUTF() throws IOException
196     {
197         return this.dataInputStream.readUTF();
198     }
199 
200     /** {@inheritDoc} */
201     @Override
202     public String readLine()
203     {
204         throw new UnsupportedOperationException("Binary reading does not support readLine method");
205     }
206 
207     /**
208      * reads UTF from the stream.
209      * @param dataInput DataInput; data input
210      * @return String the value
211      * @throws IOException on read failure
212      */
213     public static final String readUTF(final DataInput dataInput) throws IOException
214     {
215         return DataInputStream.readUTF(dataInput);
216     }
217 
218     /**
219      * @throws IOException on close failure
220      */
221     public void close() throws IOException
222     {
223         this.dataInputStream.close();
224     }
225 
226     /**
227      * Return the Endianness, i.e., big endian or little endian encoding.
228      * @return Endianness; big endian or little endian encoding
229      */
230     public Endianness getEndianness()
231     {
232         return this.endianness;
233     }
234 
235     /**
236      * Set the Endianness, i.e., big endian or little endian encoding.
237      * @param endianness Endianness; big endian or little endian encoding
238      */
239     public void setEndianness(final Endianness endianness)
240     {
241         this.endianness = endianness;
242     }
243 
244 }