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    *      http://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 java.io.IOException;
20  
21  import org.apache.commons.io.output.ByteArrayOutputStream;
22  
23  import junit.framework.TestCase;
24  
25  
26  /**
27   * @author Scott Sanders (sanders at apache dot org)
28   * @author Marc Johnson (mjohnson at apache dot org)
29   * @version $Revision: 437567 $ $Date: 2006-08-28 08:39:07 +0200 (Mo, 28 Aug 2006) $
30   */
31  
32  public class HexDumpTest extends TestCase {
33  
34      /**
35       * Creates new HexDumpTest
36       *
37       * @param name
38       */
39  
40      public HexDumpTest(String name) {
41          super(name);
42      }
43  
44      private char toHex(int n) {
45          char[] hexChars =
46                  {
47                      '0', '1', '2', '3', '4', '5', '6', '7',
48                      '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
49                  };
50  
51          return hexChars[n % 16];
52      }
53  
54      /**
55       * test dump method
56       *
57       * @exception IOException
58       */
59  
60      public void testDump()
61              throws IOException {
62          byte[] testArray = new byte[256];
63  
64          for (int j = 0; j < 256; j++) {
65              testArray[j] = (byte) j;
66          }
67          ByteArrayOutputStream stream = new ByteArrayOutputStream();
68  
69          HexDump.dump(testArray, 0, stream, 0);
70          byte[] outputArray = new byte[16 * (73 + HexDump.EOL.length())];
71  
72          for (int j = 0; j < 16; j++) {
73              int offset = (73 + HexDump.EOL.length()) * j;
74  
75              outputArray[offset++] = (byte) '0';
76              outputArray[offset++] = (byte) '0';
77              outputArray[offset++] = (byte) '0';
78              outputArray[offset++] = (byte) '0';
79              outputArray[offset++] = (byte) '0';
80              outputArray[offset++] = (byte) '0';
81              outputArray[offset++] = (byte) toHex(j);
82              outputArray[offset++] = (byte) '0';
83              outputArray[offset++] = (byte) ' ';
84              for (int k = 0; k < 16; k++) {
85                  outputArray[offset++] = (byte) toHex(j);
86                  outputArray[offset++] = (byte) toHex(k);
87                  outputArray[offset++] = (byte) ' ';
88              }
89              for (int k = 0; k < 16; k++) {
90                  outputArray[offset++] = (byte) toAscii((j * 16) + k);
91              }
92              System.arraycopy(HexDump.EOL.getBytes(), 0, outputArray, offset,
93                      HexDump.EOL.getBytes().length);
94          }
95          byte[] actualOutput = stream.toByteArray();
96  
97          assertEquals("array size mismatch", outputArray.length,
98                  actualOutput.length);
99          for (int j = 0; j < outputArray.length; j++) {
100             assertEquals("array[ " + j + "] mismatch", outputArray[j],
101                     actualOutput[j]);
102         }
103 
104         // verify proper behavior with non-zero offset
105         stream = new ByteArrayOutputStream();
106         HexDump.dump(testArray, 0x10000000, stream, 0);
107         outputArray = new byte[16 * (73 + HexDump.EOL.length())];
108         for (int j = 0; j < 16; j++) {
109             int offset = (73 + HexDump.EOL.length()) * j;
110 
111             outputArray[offset++] = (byte) '1';
112             outputArray[offset++] = (byte) '0';
113             outputArray[offset++] = (byte) '0';
114             outputArray[offset++] = (byte) '0';
115             outputArray[offset++] = (byte) '0';
116             outputArray[offset++] = (byte) '0';
117             outputArray[offset++] = (byte) toHex(j);
118             outputArray[offset++] = (byte) '0';
119             outputArray[offset++] = (byte) ' ';
120             for (int k = 0; k < 16; k++) {
121                 outputArray[offset++] = (byte) toHex(j);
122                 outputArray[offset++] = (byte) toHex(k);
123                 outputArray[offset++] = (byte) ' ';
124             }
125             for (int k = 0; k < 16; k++) {
126                 outputArray[offset++] = (byte) toAscii((j * 16) + k);
127             }
128             System.arraycopy(HexDump.EOL.getBytes(), 0, outputArray, offset,
129                     HexDump.EOL.getBytes().length);
130         }
131         actualOutput = stream.toByteArray();
132         assertEquals("array size mismatch", outputArray.length,
133                 actualOutput.length);
134         for (int j = 0; j < outputArray.length; j++) {
135             assertEquals("array[ " + j + "] mismatch", outputArray[j],
136                     actualOutput[j]);
137         }
138 
139         // verify proper behavior with negative offset
140         stream = new ByteArrayOutputStream();
141         HexDump.dump(testArray, 0xFF000000, stream, 0);
142         outputArray = new byte[16 * (73 + HexDump.EOL.length())];
143         for (int j = 0; j < 16; j++) {
144             int offset = (73 + HexDump.EOL.length()) * j;
145 
146             outputArray[offset++] = (byte) 'F';
147             outputArray[offset++] = (byte) 'F';
148             outputArray[offset++] = (byte) '0';
149             outputArray[offset++] = (byte) '0';
150             outputArray[offset++] = (byte) '0';
151             outputArray[offset++] = (byte) '0';
152             outputArray[offset++] = (byte) toHex(j);
153             outputArray[offset++] = (byte) '0';
154             outputArray[offset++] = (byte) ' ';
155             for (int k = 0; k < 16; k++) {
156                 outputArray[offset++] = (byte) toHex(j);
157                 outputArray[offset++] = (byte) toHex(k);
158                 outputArray[offset++] = (byte) ' ';
159             }
160             for (int k = 0; k < 16; k++) {
161                 outputArray[offset++] = (byte) toAscii((j * 16) + k);
162             }
163             System.arraycopy(HexDump.EOL.getBytes(), 0, outputArray, offset,
164                     HexDump.EOL.getBytes().length);
165         }
166         actualOutput = stream.toByteArray();
167         assertEquals("array size mismatch", outputArray.length,
168                 actualOutput.length);
169         for (int j = 0; j < outputArray.length; j++) {
170             assertEquals("array[ " + j + "] mismatch", outputArray[j],
171                     actualOutput[j]);
172         }
173 
174         // verify proper behavior with non-zero index
175         stream = new ByteArrayOutputStream();
176         HexDump.dump(testArray, 0x10000000, stream, 0x81);
177         outputArray = new byte[(8 * (73 + HexDump.EOL.length())) - 1];
178         for (int j = 0; j < 8; j++) {
179             int offset = (73 + HexDump.EOL.length()) * j;
180 
181             outputArray[offset++] = (byte) '1';
182             outputArray[offset++] = (byte) '0';
183             outputArray[offset++] = (byte) '0';
184             outputArray[offset++] = (byte) '0';
185             outputArray[offset++] = (byte) '0';
186             outputArray[offset++] = (byte) '0';
187             outputArray[offset++] = (byte) toHex(j + 8);
188             outputArray[offset++] = (byte) '1';
189             outputArray[offset++] = (byte) ' ';
190             for (int k = 0; k < 16; k++) {
191                 int index = 0x81 + (j * 16) + k;
192 
193                 if (index < 0x100) {
194                     outputArray[offset++] = (byte) toHex(index / 16);
195                     outputArray[offset++] = (byte) toHex(index);
196                 } else {
197                     outputArray[offset++] = (byte) ' ';
198                     outputArray[offset++] = (byte) ' ';
199                 }
200                 outputArray[offset++] = (byte) ' ';
201             }
202             for (int k = 0; k < 16; k++) {
203                 int index = 0x81 + (j * 16) + k;
204 
205                 if (index < 0x100) {
206                     outputArray[offset++] = (byte) toAscii(index);
207                 }
208             }
209             System.arraycopy(HexDump.EOL.getBytes(), 0, outputArray, offset,
210                     HexDump.EOL.getBytes().length);
211         }
212         actualOutput = stream.toByteArray();
213         assertEquals("array size mismatch", outputArray.length,
214                 actualOutput.length);
215         for (int j = 0; j < outputArray.length; j++) {
216             assertEquals("array[ " + j + "] mismatch", outputArray[j],
217                     actualOutput[j]);
218         }
219 
220         // verify proper behavior with negative index
221         try {
222             HexDump.dump(testArray, 0x10000000, new ByteArrayOutputStream(),
223                     -1);
224             fail("should have caught ArrayIndexOutOfBoundsException on negative index");
225         } catch (ArrayIndexOutOfBoundsException ignored_exception) {
226 
227             // as expected
228         }
229 
230         // verify proper behavior with index that is too large
231         try {
232             HexDump.dump(testArray, 0x10000000, new ByteArrayOutputStream(),
233                     testArray.length);
234             fail("should have caught ArrayIndexOutOfBoundsException on large index");
235         } catch (ArrayIndexOutOfBoundsException ignored_exception) {
236 
237             // as expected
238         }
239 
240         // verify proper behavior with null stream
241         try {
242             HexDump.dump(testArray, 0x10000000, null, 0);
243             fail("should have caught IllegalArgumentException on negative index");
244         } catch (IllegalArgumentException ignored_exception) {
245 
246             // as expected
247         }
248     }
249 
250     private char toAscii(int c) {
251         char rval = '.';
252 
253         if ((c >= 32) && (c <= 126)) {
254             rval = (char) c;
255         }
256         return rval;
257     }
258 
259     /**
260      * main method to run the unit tests
261      *
262      * @param ignored_args
263      */
264 
265     public static void main(String[] ignored_args) {
266         System.out.println("Testing io.HexDump functionality");
267         junit.textui.TestRunner.run(HexDumpTest.class);
268     }
269 }