View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertThrows;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.ByteArrayOutputStream;
24  import java.io.EOFException;
25  import java.io.IOException;
26  
27  import org.junit.jupiter.api.Test;
28  
29  /**
30   * Tests {@link EndianUtils}.
31   */
32  class EndianUtilsTest {
33  
34      @Test
35      void testCtor() {
36          new EndianUtils();
37          // Constructor does not blow up.
38      }
39  
40      @Test
41      void testEOFException() {
42          final ByteArrayInputStream input = new ByteArrayInputStream(new byte[] {});
43          assertThrows(EOFException.class, () -> EndianUtils.readSwappedDouble(input));
44      }
45  
46      @Test
47      void testInvalidOffset() throws IOException {
48          final byte[] bytes = {};
49  
50          assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedInteger(bytes, 0));
51          assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedLong(bytes, 0));
52          assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedShort(bytes, 0));
53          assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedUnsignedInteger(bytes, 0));
54          assertThrows(IllegalArgumentException.class, () -> EndianUtils.readSwappedUnsignedShort(bytes, 0));
55          assertThrows(IllegalArgumentException.class, () -> EndianUtils.writeSwappedInteger(bytes, 0, 0));
56          assertThrows(IllegalArgumentException.class, () -> EndianUtils.writeSwappedLong(bytes, 0, 0L));
57          assertThrows(IllegalArgumentException.class, () -> EndianUtils.writeSwappedShort(bytes, 0, (short) 0));
58      }
59  
60      @Test
61      void testReadSwappedDouble() throws IOException {
62          final byte[] bytes = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
63          final double d1 = Double.longBitsToDouble(0x0102030405060708L);
64          final double d2 = EndianUtils.readSwappedDouble(bytes, 0);
65          assertEquals(d1, d2, 0.0);
66  
67          final ByteArrayInputStream input = new ByteArrayInputStream(bytes);
68          assertEquals(d1, EndianUtils.readSwappedDouble(input), 0.0);
69      }
70  
71      @Test
72      void testReadSwappedFloat() throws IOException {
73          final byte[] bytes = { 0x04, 0x03, 0x02, 0x01 };
74          final float f1 = Float.intBitsToFloat(0x01020304);
75          final float f2 = EndianUtils.readSwappedFloat(bytes, 0);
76          assertEquals(f1, f2, 0.0);
77  
78          final ByteArrayInputStream input = new ByteArrayInputStream(bytes);
79          assertEquals(f1, EndianUtils.readSwappedFloat(input), 0.0);
80      }
81  
82      @Test
83      void testReadSwappedInteger() throws IOException {
84          final byte[] bytes = { 0x04, 0x03, 0x02, 0x01 };
85          assertEquals(0x01020304, EndianUtils.readSwappedInteger(bytes, 0));
86  
87          final ByteArrayInputStream input = new ByteArrayInputStream(bytes);
88          assertEquals(0x01020304, EndianUtils.readSwappedInteger(input));
89      }
90  
91      @Test
92      void testReadSwappedLong() throws IOException {
93          final byte[] bytes = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
94          assertEquals(0x0102030405060708L, EndianUtils.readSwappedLong(bytes, 0));
95  
96          final ByteArrayInputStream input = new ByteArrayInputStream(bytes);
97          assertEquals(0x0102030405060708L, EndianUtils.readSwappedLong(input));
98      }
99  
100     @Test
101     void testReadSwappedShort() throws IOException {
102         final byte[] bytes = { 0x02, 0x01 };
103         assertEquals(0x0102, EndianUtils.readSwappedShort(bytes, 0));
104 
105         final ByteArrayInputStream input = new ByteArrayInputStream(bytes);
106         assertEquals(0x0102, EndianUtils.readSwappedShort(input));
107     }
108 
109     @Test
110     void testReadSwappedUnsignedInteger() throws IOException {
111         final byte[] bytes = { 0x04, 0x03, 0x02, 0x01 };
112         assertEquals(0x0000000001020304L, EndianUtils.readSwappedUnsignedInteger(bytes, 0));
113 
114         final ByteArrayInputStream input = new ByteArrayInputStream(bytes);
115         assertEquals(0x0000000001020304L, EndianUtils.readSwappedUnsignedInteger(input));
116     }
117 
118     @Test
119     void testReadSwappedUnsignedShort() throws IOException {
120         final byte[] bytes = { 0x02, 0x01 };
121         assertEquals(0x00000102, EndianUtils.readSwappedUnsignedShort(bytes, 0));
122 
123         final ByteArrayInputStream input = new ByteArrayInputStream(bytes);
124         assertEquals(0x00000102, EndianUtils.readSwappedUnsignedShort(input));
125     }
126 
127     @Test
128     void testSwapDouble() {
129         assertEquals(0.0, EndianUtils.swapDouble(0.0), 0.0);
130         final double d1 = Double.longBitsToDouble(0x0102030405060708L);
131         final double d2 = Double.longBitsToDouble(0x0807060504030201L);
132         assertEquals(d2, EndianUtils.swapDouble(d1), 0.0);
133     }
134 
135     @Test
136     void testSwapFloat() {
137         assertEquals(0.0f, EndianUtils.swapFloat(0.0f), 0.0);
138         final float f1 = Float.intBitsToFloat(0x01020304);
139         final float f2 = Float.intBitsToFloat(0x04030201);
140         assertEquals(f2, EndianUtils.swapFloat(f1), 0.0);
141     }
142 
143     @Test
144     void testSwapInteger() {
145         assertEquals(0, EndianUtils.swapInteger(0));
146         assertEquals(0x04030201, EndianUtils.swapInteger(0x01020304));
147         assertEquals(0x01000000, EndianUtils.swapInteger(0x00000001));
148         assertEquals(0x00000001, EndianUtils.swapInteger(0x01000000));
149         assertEquals(0x11111111, EndianUtils.swapInteger(0x11111111));
150         assertEquals(0xabcdef10, EndianUtils.swapInteger(0x10efcdab));
151         assertEquals(0xab, EndianUtils.swapInteger(0xab000000));
152     }
153 
154     @Test
155     void testSwapLong() {
156         assertEquals(0, EndianUtils.swapLong(0));
157         assertEquals(0x0807060504030201L, EndianUtils.swapLong(0x0102030405060708L));
158         assertEquals(0xffffffffffffffffL, EndianUtils.swapLong(0xffffffffffffffffL));
159         assertEquals(0xab, EndianUtils.swapLong(0xab00000000000000L));
160     }
161 
162     @Test
163     void testSwapShort() {
164         assertEquals((short) 0, EndianUtils.swapShort((short) 0));
165         assertEquals((short) 0x0201, EndianUtils.swapShort((short) 0x0102));
166         assertEquals((short) 0xffff, EndianUtils.swapShort((short) 0xffff));
167         assertEquals((short) 0x0102, EndianUtils.swapShort((short) 0x0201));
168     }
169 
170     /**
171      * Tests all swapXxxx methods for symmetry when going from one endian to another and back again.
172      */
173     @Test
174     void testSymmetry() {
175         assertEquals((short) 0x0102, EndianUtils.swapShort(EndianUtils.swapShort((short) 0x0102)));
176         assertEquals(0x01020304, EndianUtils.swapInteger(EndianUtils.swapInteger(0x01020304)));
177         assertEquals(0x0102030405060708L, EndianUtils.swapLong(EndianUtils.swapLong(0x0102030405060708L)));
178         final float f1 = Float.intBitsToFloat(0x01020304);
179         assertEquals(f1, EndianUtils.swapFloat(EndianUtils.swapFloat(f1)), 0.0);
180         final double d1 = Double.longBitsToDouble(0x0102030405060708L);
181         assertEquals(d1, EndianUtils.swapDouble(EndianUtils.swapDouble(d1)), 0.0);
182     }
183 
184     // tests #IO-101
185     @Test
186     void testSymmetryOfLong() {
187 
188         final double[] tests = { 34.345, -345.5645, 545.12, 10.043, 7.123456789123 };
189         for (final double test : tests) {
190 
191             // testing the real problem
192             byte[] buffer = new byte[8];
193             final long ln1 = Double.doubleToLongBits(test);
194             EndianUtils.writeSwappedLong(buffer, 0, ln1);
195             final long ln2 = EndianUtils.readSwappedLong(buffer, 0);
196             assertEquals(ln1, ln2);
197 
198             // testing the bug report
199             buffer = new byte[8];
200             EndianUtils.writeSwappedDouble(buffer, 0, test);
201             final double val = EndianUtils.readSwappedDouble(buffer, 0);
202             assertEquals(test, val, 0);
203         }
204     }
205 
206     // tests #IO-117
207     @Test
208     void testUnsignedOverrun() throws Exception {
209         final byte[] target = { 0, 0, 0, (byte) 0x80 };
210         final long expected = 0x80000000L;
211 
212         long actual = EndianUtils.readSwappedUnsignedInteger(target, 0);
213         assertEquals(expected, actual, "readSwappedUnsignedInteger(byte[], int) was incorrect");
214 
215         final ByteArrayInputStream in = new ByteArrayInputStream(target);
216         actual = EndianUtils.readSwappedUnsignedInteger(in);
217         assertEquals(expected, actual, "readSwappedUnsignedInteger(InputStream) was incorrect");
218     }
219 
220     @Test
221     void testWriteSwappedDouble() throws IOException {
222         byte[] bytes = new byte[8];
223         final double d1 = Double.longBitsToDouble(0x0102030405060708L);
224         EndianUtils.writeSwappedDouble(bytes, 0, d1);
225         assertEquals(0x08, bytes[0]);
226         assertEquals(0x07, bytes[1]);
227         assertEquals(0x06, bytes[2]);
228         assertEquals(0x05, bytes[3]);
229         assertEquals(0x04, bytes[4]);
230         assertEquals(0x03, bytes[5]);
231         assertEquals(0x02, bytes[6]);
232         assertEquals(0x01, bytes[7]);
233 
234         final ByteArrayOutputStream baos = new ByteArrayOutputStream(8);
235         EndianUtils.writeSwappedDouble(baos, d1);
236         bytes = baos.toByteArray();
237         assertEquals(0x08, bytes[0]);
238         assertEquals(0x07, bytes[1]);
239         assertEquals(0x06, bytes[2]);
240         assertEquals(0x05, bytes[3]);
241         assertEquals(0x04, bytes[4]);
242         assertEquals(0x03, bytes[5]);
243         assertEquals(0x02, bytes[6]);
244         assertEquals(0x01, bytes[7]);
245     }
246 
247     @Test
248     void testWriteSwappedFloat() throws IOException {
249         byte[] bytes = new byte[4];
250         final float f1 = Float.intBitsToFloat(0x01020304);
251         EndianUtils.writeSwappedFloat(bytes, 0, f1);
252         assertEquals(0x04, bytes[0]);
253         assertEquals(0x03, bytes[1]);
254         assertEquals(0x02, bytes[2]);
255         assertEquals(0x01, bytes[3]);
256 
257         final ByteArrayOutputStream baos = new ByteArrayOutputStream(4);
258         EndianUtils.writeSwappedFloat(baos, f1);
259         bytes = baos.toByteArray();
260         assertEquals(0x04, bytes[0]);
261         assertEquals(0x03, bytes[1]);
262         assertEquals(0x02, bytes[2]);
263         assertEquals(0x01, bytes[3]);
264     }
265 
266     @Test
267     void testWriteSwappedInteger() throws IOException {
268         byte[] bytes = new byte[4];
269         EndianUtils.writeSwappedInteger(bytes, 0, 0x01020304);
270         assertEquals(0x04, bytes[0]);
271         assertEquals(0x03, bytes[1]);
272         assertEquals(0x02, bytes[2]);
273         assertEquals(0x01, bytes[3]);
274 
275         final ByteArrayOutputStream baos = new ByteArrayOutputStream(4);
276         EndianUtils.writeSwappedInteger(baos, 0x01020304);
277         bytes = baos.toByteArray();
278         assertEquals(0x04, bytes[0]);
279         assertEquals(0x03, bytes[1]);
280         assertEquals(0x02, bytes[2]);
281         assertEquals(0x01, bytes[3]);
282     }
283 
284     @Test
285     void testWriteSwappedLong() throws IOException {
286         byte[] bytes = new byte[8];
287         EndianUtils.writeSwappedLong(bytes, 0, 0x0102030405060708L);
288         assertEquals(0x08, bytes[0]);
289         assertEquals(0x07, bytes[1]);
290         assertEquals(0x06, bytes[2]);
291         assertEquals(0x05, bytes[3]);
292         assertEquals(0x04, bytes[4]);
293         assertEquals(0x03, bytes[5]);
294         assertEquals(0x02, bytes[6]);
295         assertEquals(0x01, bytes[7]);
296 
297         final ByteArrayOutputStream baos = new ByteArrayOutputStream(8);
298         EndianUtils.writeSwappedLong(baos, 0x0102030405060708L);
299         bytes = baos.toByteArray();
300         assertEquals(0x08, bytes[0]);
301         assertEquals(0x07, bytes[1]);
302         assertEquals(0x06, bytes[2]);
303         assertEquals(0x05, bytes[3]);
304         assertEquals(0x04, bytes[4]);
305         assertEquals(0x03, bytes[5]);
306         assertEquals(0x02, bytes[6]);
307         assertEquals(0x01, bytes[7]);
308     }
309 
310     @Test
311     void testWriteSwappedShort() throws IOException {
312         byte[] bytes = new byte[2];
313         EndianUtils.writeSwappedShort(bytes, 0, (short) 0x0102);
314         assertEquals(0x02, bytes[0]);
315         assertEquals(0x01, bytes[1]);
316 
317         final ByteArrayOutputStream baos = new ByteArrayOutputStream(2);
318         EndianUtils.writeSwappedShort(baos, (short) 0x0102);
319         bytes = baos.toByteArray();
320         assertEquals(0x02, bytes[0]);
321         assertEquals(0x01, bytes[1]);
322     }
323 
324 }