Coverage Report - org.apache.commons.io.HexDump
 
Classes in this File Line Coverage Branch Coverage Complexity
HexDump
94%
35/37
100%
24/24
4.5
 
 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  
 import java.nio.charset.Charset;
 22  
 
 23  
 /**
 24  
  * Dumps data in hexadecimal format.
 25  
  * <p>
 26  
  * Provides a single function to take an array of bytes and display it
 27  
  * in hexadecimal form.
 28  
  * <p>
 29  
  * Origin of code: POI.
 30  
  *
 31  
  * @version $Id: HexDump.java 1471767 2013-04-24 23:24:19Z sebb $
 32  
  */
 33  
 public class HexDump {
 34  
 
 35  
     /**
 36  
      * Instances should NOT be constructed in standard programming.
 37  
      */
 38  
     public HexDump() {
 39  0
         super();
 40  0
     }
 41  
 
 42  
     /**
 43  
      * Dump an array of bytes to an OutputStream. The output is formatted
 44  
      * for human inspection, with a hexadecimal offset followed by the
 45  
      * hexadecimal values of the next 16 bytes of data and the printable ASCII
 46  
      * characters (if any) that those bytes represent printed per each line
 47  
      * of output.
 48  
      * <p>
 49  
      * The offset argument specifies the start offset of the data array
 50  
      * within a larger entity like a file or an incoming stream. For example,
 51  
      * if the data array contains the third kibibyte of a file, then the
 52  
      * offset argument should be set to 2048. The offset value printed
 53  
      * at the beginning of each line indicates where in that larger entity
 54  
      * the first byte on that line is located.
 55  
      * <p>
 56  
      * All bytes between the given index (inclusive) and the end of the
 57  
      * data array are dumped.
 58  
      *
 59  
      * @param data  the byte array to be dumped
 60  
      * @param offset  offset of the byte array within a larger entity
 61  
      * @param stream  the OutputStream to which the data is to be
 62  
      *               written
 63  
      * @param index initial index into the byte array
 64  
      *
 65  
      * @throws IOException is thrown if anything goes wrong writing
 66  
      *         the data to stream
 67  
      * @throws ArrayIndexOutOfBoundsException if the index is
 68  
      *         outside the data array's bounds
 69  
      * @throws IllegalArgumentException if the output stream is null
 70  
      */
 71  
 
 72  
     public static void dump(final byte[] data, final long offset,
 73  
                             final OutputStream stream, final int index)
 74  
             throws IOException, ArrayIndexOutOfBoundsException,
 75  
             IllegalArgumentException {
 76  
 
 77  14
         if (index < 0 || index >= data.length) {
 78  4
             throw new ArrayIndexOutOfBoundsException(
 79  
                     "illegal index: " + index + " into array of length "
 80  
                     + data.length);
 81  
         }
 82  10
         if (stream == null) {
 83  2
             throw new IllegalArgumentException("cannot write to nullstream");
 84  
         }
 85  8
         long display_offset = offset + index;
 86  8
         final StringBuilder buffer = new StringBuilder(74);
 87  
 
 88  120
         for (int j = index; j < data.length; j += 16) {
 89  112
             int chars_read = data.length - j;
 90  
 
 91  112
             if (chars_read > 16) {
 92  104
                 chars_read = 16;
 93  
             }
 94  112
             dump(buffer, display_offset).append(' ');
 95  1904
             for (int k = 0; k < 16; k++) {
 96  1792
                 if (k < chars_read) {
 97  1790
                     dump(buffer, data[k + j]);
 98  
                 } else {
 99  2
                     buffer.append("  ");
 100  
                 }
 101  1792
                 buffer.append(' ');
 102  
             }
 103  1902
             for (int k = 0; k < chars_read; k++) {
 104  1790
                 if (data[k + j] >= ' ' && data[k + j] < 127) {
 105  570
                     buffer.append((char) data[k + j]);
 106  
                 } else {
 107  1220
                     buffer.append('.');
 108  
                 }
 109  
             }
 110  112
             buffer.append(EOL);
 111  
             // make explicit the dependency on the default encoding
 112  112
             stream.write(buffer.toString().getBytes(Charset.defaultCharset()));
 113  112
             stream.flush();
 114  112
             buffer.setLength(0);
 115  112
             display_offset += chars_read;
 116  
         }
 117  8
     }
 118  
 
 119  
     /**
 120  
      * The line-separator (initializes to "line.separator" system property.
 121  
      */
 122  2
     public static final String EOL =
 123  
             System.getProperty("line.separator");
 124  2
     private static final char[] _hexcodes =
 125  
             {
 126  
                 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 127  
                 'A', 'B', 'C', 'D', 'E', 'F'
 128  
             };
 129  2
     private static final int[] _shifts =
 130  
             {
 131  
                 28, 24, 20, 16, 12, 8, 4, 0
 132  
             };
 133  
 
 134  
     /**
 135  
      * Dump a long value into a StringBuilder.
 136  
      *
 137  
      * @param _lbuffer the StringBuilder to dump the value in
 138  
      * @param value  the long value to be dumped
 139  
      * @return StringBuilder containing the dumped value.
 140  
      */
 141  
     private static StringBuilder dump(final StringBuilder _lbuffer, final long value) {
 142  1008
         for (int j = 0; j < 8; j++) {
 143  896
             _lbuffer
 144  
                     .append(_hexcodes[(int) (value >> _shifts[j]) & 15]);
 145  
         }
 146  112
         return _lbuffer;
 147  
     }
 148  
 
 149  
     /**
 150  
      * Dump a byte value into a StringBuilder.
 151  
      *
 152  
      * @param _cbuffer the StringBuilder to dump the value in
 153  
      * @param value  the byte value to be dumped
 154  
      * @return StringBuilder containing the dumped value.
 155  
      */
 156  
     private static StringBuilder dump(final StringBuilder _cbuffer, final byte value) {
 157  5370
         for (int j = 0; j < 2; j++) {
 158  3580
             _cbuffer.append(_hexcodes[value >> _shifts[j + 6] & 15]);
 159  
         }
 160  1790
         return _cbuffer;
 161  
     }
 162  
 
 163  
 }