• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import java.io.OutputStream;
21 
22 /**
23  * Dumps data in hexadecimal format.
24  * <p>
25  * Provides a single function to take an array of bytes and display it
26  * in hexadecimal form.
27  * <p>
28  * Origin of code: POI.
29  *
30  * @author Scott Sanders
31  * @author Marc Johnson
32  * @version $Id: HexDump.java 596667 2007-11-20 13:50:14Z niallp $
33  */
34 public class HexDump {
35 
36     /**
37      * Instances should NOT be constructed in standard programming.
38      */
HexDump()39     public HexDump() {
40         super();
41     }
42 
43     /**
44      * Dump an array of bytes to an OutputStream.
45      *
46      * @param data  the byte array to be dumped
47      * @param offset  its offset, whatever that might mean
48      * @param stream  the OutputStream to which the data is to be
49      *               written
50      * @param index initial index into the byte array
51      *
52      * @throws IOException is thrown if anything goes wrong writing
53      *         the data to stream
54      * @throws ArrayIndexOutOfBoundsException if the index is
55      *         outside the data array's bounds
56      * @throws IllegalArgumentException if the output stream is null
57      */
58 
dump(byte[] data, long offset, OutputStream stream, int index)59     public static void dump(byte[] data, long offset,
60                             OutputStream stream, int index)
61             throws IOException, ArrayIndexOutOfBoundsException,
62             IllegalArgumentException {
63 
64         if ((index < 0) || (index >= data.length)) {
65             throw new ArrayIndexOutOfBoundsException(
66                     "illegal index: " + index + " into array of length "
67                     + data.length);
68         }
69         if (stream == null) {
70             throw new IllegalArgumentException("cannot write to nullstream");
71         }
72         long display_offset = offset + index;
73         StringBuffer buffer = new StringBuffer(74);
74 
75         for (int j = index; j < data.length; j += 16) {
76             int chars_read = data.length - j;
77 
78             if (chars_read > 16) {
79                 chars_read = 16;
80             }
81             dump(buffer, display_offset).append(' ');
82             for (int k = 0; k < 16; k++) {
83                 if (k < chars_read) {
84                     dump(buffer, data[k + j]);
85                 } else {
86                     buffer.append("  ");
87                 }
88                 buffer.append(' ');
89             }
90             for (int k = 0; k < chars_read; k++) {
91                 if ((data[k + j] >= ' ') && (data[k + j] < 127)) {
92                     buffer.append((char) data[k + j]);
93                 } else {
94                     buffer.append('.');
95                 }
96             }
97             buffer.append(EOL);
98             stream.write(buffer.toString().getBytes());
99             stream.flush();
100             buffer.setLength(0);
101             display_offset += chars_read;
102         }
103     }
104 
105     /**
106      * The line-separator (initializes to "line.separator" system property.
107      */
108     public static final String EOL =
109             System.getProperty("line.separator");
110     private static final char[] _hexcodes =
111             {
112                 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
113                 'A', 'B', 'C', 'D', 'E', 'F'
114             };
115     private static final int[] _shifts =
116             {
117                 28, 24, 20, 16, 12, 8, 4, 0
118             };
119 
120     /**
121      * Dump a long value into a StringBuffer.
122      *
123      * @param _lbuffer the StringBuffer to dump the value in
124      * @param value  the long value to be dumped
125      * @return StringBuffer containing the dumped value.
126      */
dump(StringBuffer _lbuffer, long value)127     private static StringBuffer dump(StringBuffer _lbuffer, long value) {
128         for (int j = 0; j < 8; j++) {
129             _lbuffer
130                     .append(_hexcodes[((int) (value >> _shifts[j])) & 15]);
131         }
132         return _lbuffer;
133     }
134 
135     /**
136      * Dump a byte value into a StringBuffer.
137      *
138      * @param _cbuffer the StringBuffer to dump the value in
139      * @param value  the byte value to be dumped
140      * @return StringBuffer containing the dumped value.
141      */
dump(StringBuffer _cbuffer, byte value)142     private static StringBuffer dump(StringBuffer _cbuffer, byte value) {
143         for (int j = 0; j < 2; j++) {
144             _cbuffer.append(_hexcodes[(value >> _shifts[j + 6]) & 15]);
145         }
146         return _cbuffer;
147     }
148 
149 }
150