View Javadoc
1   package org.djutils.decoderdumper;
2   
3   import java.io.IOException;
4   
5   /**
6    * Dump bytes as hexadecimal numbers
7    * <p>
8    * Copyright (c) 2013-2021 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
9    * BSD-style license. See <a href="https://djutils.org/docs/current/djutils/licenses.html">DJUTILS License</a>.
10   * <p>
11   * @version $Revision$, $LastChangedDate$, by $Author$, initial version Jan 3, 2019 <br>
12   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
13   * @author <a href="https://www.tudelft.nl/staff/p.knoppers/">Peter Knoppers</a>
14   */
15  public class HexDecoder implements Decoder
16  {
17      /** Prototype output line. */
18      private final String prototypeLine;
19  
20      /** Number of fields on an output line. */
21      private int fieldsPerLine;
22  
23      /** Insert one extra space every N fields. */
24      private final int extraSpaceAfterEvery;
25  
26      /**
27       * Construct a new HexDecoder.
28       * @param fieldsPerLine int; maximum number of hex values on one output line this.extraSpaceAfterEvery =
29       *            extraSpaceAfterEvery;
30       * @param extraSpaceAfterEvery int; insert an extra space after every N fields
31       */
32      public HexDecoder(final int fieldsPerLine, final int extraSpaceAfterEvery)
33      {
34          this.fieldsPerLine = fieldsPerLine;
35          this.extraSpaceAfterEvery = extraSpaceAfterEvery > 0 ? extraSpaceAfterEvery : Integer.MAX_VALUE;
36          String format =
37                  String.format("%%%ds", fieldsPerLine * 2 + fieldsPerLine - 1 + (fieldsPerLine - 1) / this.extraSpaceAfterEvery);
38          this.prototypeLine = String.format(format, "");
39      }
40  
41      /** String builder for current output line. */
42      private StringBuilder buffer = new StringBuilder();
43  
44      /** {@inheritDoc} */
45      @Override
46      public String getResult()
47      {
48          String result = this.buffer.toString();
49          this.buffer.setLength(0);
50          return result;
51      }
52  
53      /** {@inheritDoc} */
54      @Override
55      public int getMaximumWidth()
56      {
57          return this.prototypeLine.length();
58      }
59  
60      /** {@inheritDoc} */
61      @Override
62      public boolean append(final int address, final byte theByte) throws IOException
63      {
64          if (this.buffer.length() == 0)
65          {
66              this.buffer.append(this.prototypeLine);
67          }
68          int lineByte = address % this.fieldsPerLine;
69          int index = lineByte * 3 + lineByte / this.extraSpaceAfterEvery;
70          this.buffer.replace(index, index + 2, String.format("%02x", theByte));
71          return lineByte == this.fieldsPerLine - 1;
72      }
73  
74      /** {@inheritDoc} */
75      @Override
76      public boolean ignoreForIdenticalOutputCheck()
77      {
78          return false;
79      }
80  
81      /** {@inheritDoc} */
82      @Override
83      public String toString()
84      {
85          return "HexDecoder [buffer=" + this.buffer + "]";
86      }
87  
88  }