Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

224
LINES

< > BotCompany Repo | #1031892 // HexDumpEncoder

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (251L/2K).

1  
import java.nio.ByteBuffer;
2  
3  
/**
4  
 * This is a drop-in replacement for Sun's internal <code>sun.misc.HexDumpEncoder</code> class. It should be completely
5  
 * compatible with the output from Sun's encoder, making it possible to get rid of the now forbidden reference to the
6  
 * internal class without affecting the application's behavior in any way.
7  
 * 
8  
 * @author Erik Wramner
9  
 */
10  
sclass HexDumpEncoder {
11  
    private static final int BYTES_PER_LINE = 16;
12  
    private static final int BYTES_PER_GROUP = 8;
13  
    private static final String LINE_SEPARATOR = System.getProperty("line.separator", "\n");
14  
15  
    public String encodeBuffer(byte[] buf) {
16  
        try {
17  
            Appendable sb = new StringBuilder();
18  
            internalEncode(buf, buf.length, 0, sb, false);
19  
            return sb.toString();
20  
        } catch (IOException e) {
21  
            // This should never happen
22  
            throw new IllegalStateException("IO exception from string builder", e);
23  
        }
24  
    }
25  
26  
    public void encodeBuffer(byte[] buf, OutputStream out) throws IOException {
27  
        internalEncode(buf, buf.length, 0, new OutputStreamAppendableAdapter(out), false);
28  
    }
29  
30  
    public void encodeBuffer(ByteBuffer byteBuffer, OutputStream out) throws IOException {
31  
        OutputStreamAppendableAdapter appendable = new OutputStreamAppendableAdapter(out);
32  
        internalEncode(byteBuffer, appendable, false);
33  
    }
34  
35  
    public String encodeBuffer(ByteBuffer byteBuffer) {
36  
        StringBuilder sb = new StringBuilder();
37  
        try {
38  
            internalEncode(byteBuffer, sb, false);
39  
        } catch (IOException e) {
40  
            // This should never happen
41  
            throw new IllegalStateException("IO exception from string builder", e);
42  
        }
43  
        return sb.toString();
44  
    }
45  
46  
    public void encodeBuffer(InputStream in, OutputStream out) throws IOException {
47  
        Appendable outAppendable = new OutputStreamAppendableAdapter(out);
48  
        int address = 0;
49  
        byte[] buf = new byte[BYTES_PER_LINE * 100];
50  
        int bytesRead = fillBuffer(in, buf);
51  
        while (bytesRead > 0) {
52  
            internalEncode(buf, bytesRead, address, outAppendable, false);
53  
            if (bytesRead == buf.length) {
54  
                address += bytesRead;
55  
                bytesRead = fillBuffer(in, buf);
56  
            } else {
57  
                bytesRead = 0;
58  
            }
59  
        }
60  
    }
61  
62  
    public String encode(byte[] buf) {
63  
        try {
64  
            Appendable sb = new StringBuilder();
65  
            internalEncode(buf, buf.length, 0, sb, true);
66  
            return sb.toString();
67  
        } catch (IOException e) {
68  
            // This should never happen
69  
            throw new IllegalStateException("IO exception from string builder", e);
70  
        }
71  
    }
72  
73  
    public void encode(byte[] buf, OutputStream out) throws IOException {
74  
        internalEncode(buf, buf.length, 0, new OutputStreamAppendableAdapter(out), true);
75  
    }
76  
77  
    public void encode(ByteBuffer byteBuffer, OutputStream out) throws IOException {
78  
        OutputStreamAppendableAdapter appendable = new OutputStreamAppendableAdapter(out);
79  
        internalEncode(byteBuffer, appendable, true);
80  
    }
81  
82  
    public String encode(ByteBuffer byteBuffer) {
83  
        StringBuilder sb = new StringBuilder();
84  
        try {
85  
            internalEncode(byteBuffer, sb, true);
86  
        } catch (IOException e) {
87  
            // This should never happen
88  
            throw new IllegalStateException("IO exception from string builder", e);
89  
        }
90  
        return sb.toString();
91  
    }
92  
93  
    public void encode(InputStream in, OutputStream out) throws IOException {
94  
        Appendable outAppendable = new OutputStreamAppendableAdapter(out);
95  
        int address = 0;
96  
        byte[] buf = new byte[BYTES_PER_LINE * 100];
97  
        int bytesRead = fillBuffer(in, buf);
98  
        while (bytesRead > 0) {
99  
            internalEncode(buf, bytesRead, address, outAppendable, true);
100  
            if (bytesRead == buf.length) {
101  
                address += bytesRead;
102  
                bytesRead = fillBuffer(in, buf);
103  
            } else {
104  
                bytesRead = 0;
105  
            }
106  
        }
107  
    }
108  
109  
    private int fillBuffer(InputStream in, byte[] buf) throws IOException {
110  
        int totalBytesRead = 0;
111  
        int bytesLeft = buf.length;
112  
        while (bytesLeft > 0) {
113  
            int bytesRead = in.read(buf, totalBytesRead, bytesLeft);
114  
            if (bytesRead == -1) {
115  
                break;
116  
            } else {
117  
                bytesLeft -= bytesRead;
118  
                totalBytesRead += bytesRead;
119  
            }
120  
        }
121  
        return totalBytesRead;
122  
    }
123  
124  
    private void internalEncode(ByteBuffer byteBuffer, Appendable appendable, boolean dropAsciiForPartialLine)
125  
            throws IOException {
126  
        int address = 0;
127  
        while (byteBuffer.hasRemaining()) {
128  
            byte[] buf = new byte[Math.min(byteBuffer.remaining(), BYTES_PER_LINE * 100)];
129  
            byteBuffer.get(buf);
130  
            internalEncode(buf, buf.length, address, appendable, dropAsciiForPartialLine);
131  
            address += buf.length;
132  
        }
133  
    }
134  
135  
    private void internalEncode(byte[] buf, int length, int baseAddress, Appendable sb, boolean dropAsciiForPartialLine)
136  
            throws IOException {
137  
        StringBuilder asciiStringBuilder = new StringBuilder();
138  
        for (int i = 0; i < length; i++) {
139  
            if (i % BYTES_PER_LINE == 0) {
140  
                if (asciiStringBuilder.length() > 0) {
141  
                    sb.append("  ");
142  
                    sb.append(asciiStringBuilder);
143  
                    sb.append(LINE_SEPARATOR);
144  
                    asciiStringBuilder.setLength(0);
145  
                }
146  
                appendHexDigit(sb, (byte) (((baseAddress + i) >>> 8) & 0xFF));
147  
                appendHexDigit(sb, (byte) ((baseAddress + i) & 0xFF));
148  
                sb.append(':');
149  
            } else if (i % BYTES_PER_GROUP == 0) {
150  
                sb.append("  ");
151  
            }
152  
            sb.append(' ');
153  
            final byte b = buf[i];
154  
            appendHexDigit(sb, b);
155  
            if (b >= 0x20 && b <= 0x7a) {
156  
                asciiStringBuilder.append((char) b);
157  
            } else {
158  
                asciiStringBuilder.append('.');
159  
            }
160  
        }
161  
162  
        if (dropAsciiForPartialLine) {
163  
            // Be bug compatible
164  
            if (asciiStringBuilder.length() > 0) {
165  
                sb.append(' ');
166  
                if (length % BYTES_PER_LINE == BYTES_PER_GROUP) {
167  
                    sb.append("  ");
168  
                } else if (length % BYTES_PER_LINE == 0) {
169  
                    sb.append(' ');
170  
                    sb.append(asciiStringBuilder);
171  
                    sb.append(LINE_SEPARATOR);
172  
                }
173  
            }
174  
        } else if (asciiStringBuilder.length() > 0) {
175  
            int remainingBytes = BYTES_PER_LINE - length % BYTES_PER_LINE;
176  
            if (remainingBytes != BYTES_PER_LINE) {
177  
                for (int i = 0; i < remainingBytes; i++) {
178  
                    sb.append("   ");
179  
                }
180  
                if (remainingBytes >= BYTES_PER_GROUP) {
181  
                    sb.append("  ");
182  
                }
183  
            }
184  
            sb.append("  ");
185  
            sb.append(asciiStringBuilder);
186  
            sb.append(LINE_SEPARATOR);
187  
        }
188  
    }
189  
190  
    private void appendHexDigit(Appendable sb, byte b) throws IOException {
191  
        int nibble = (char) (b >> 4 & 0xF);
192  
        sb.append((char) (nibble > 9 ? nibble - 10 + 65 : nibble + 48));
193  
        nibble = (char) (b & 0xF);
194  
        sb.append((char) (nibble > 9 ? nibble - 10 + 65 : nibble + 48));
195  
    }
196  
197  
    private static class OutputStreamAppendableAdapter implements Appendable {
198  
        private final OutputStream _out;
199  
200  
        public OutputStreamAppendableAdapter(OutputStream out) {
201  
            _out = out;
202  
        }
203  
204  
        @Override
205  
        public Appendable append(CharSequence cs) throws IOException {
206  
            append(cs, 0, cs.length());
207  
            return this;
208  
        }
209  
210  
        @Override
211  
        public Appendable append(CharSequence cs, int start, int end) throws IOException {
212  
            for (int i = start; i < end; i++) {
213  
                append(cs.charAt(i));
214  
            }
215  
            return this;
216  
        }
217  
218  
        @Override
219  
        public Appendable append(char c) throws IOException {
220  
            _out.write(c);
221  
            return this;
222  
        }
223  
    }
224  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx

No comments. add comment

Snippet ID: #1031892
Snippet name: HexDumpEncoder
Eternal ID of this version: #1031892/3
Text MD5: 7a9606d36fd6c28e3fa0e834d4090ec0
Transpilation MD5: 0b0cce7809c36fe2e9d436ce0ee2885a
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-07-24 05:36:52
Source code size: 8536 bytes / 224 lines
Pitched / IR pitched: No / No
Views / Downloads: 92 / 217
Version history: 2 change(s)
Referenced in: [show references]