Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/security/util/HexDumpEncoder.java
41159 views
1
/*
2
* Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
27
package sun.security.util;
28
29
import java.io.ByteArrayInputStream;
30
import java.io.ByteArrayOutputStream;
31
import java.io.InputStream;
32
import java.io.PrintStream;
33
import java.io.OutputStream;
34
import java.io.IOException;
35
import java.nio.ByteBuffer;
36
37
import static java.nio.charset.StandardCharsets.ISO_8859_1;
38
39
/**
40
* This class encodes a buffer into the classic: "Hexadecimal Dump" format of
41
* the past. It is useful for analyzing the contents of binary buffers.
42
* The format produced is as follows:
43
* <pre>
44
* xxxx: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ................
45
* </pre>
46
* Where xxxx is the offset into the buffer in 16 byte chunks, followed
47
* by ascii coded hexadecimal bytes followed by the ASCII representation of
48
* the bytes or '.' if they are not valid bytes.
49
*
50
* @author Chuck McManis
51
*/
52
53
public class HexDumpEncoder {
54
55
private int offset;
56
private int thisLineLength;
57
private int currentByte;
58
private byte thisLine[] = new byte[16];
59
60
static void hexDigit(PrintStream p, byte x) {
61
char c;
62
63
c = (char) ((x >> 4) & 0xf);
64
if (c > 9)
65
c = (char) ((c-10) + 'A');
66
else
67
c = (char)(c + '0');
68
p.write(c);
69
c = (char) (x & 0xf);
70
if (c > 9)
71
c = (char)((c-10) + 'A');
72
else
73
c = (char)(c + '0');
74
p.write(c);
75
}
76
77
protected int bytesPerAtom() {
78
return (1);
79
}
80
81
protected int bytesPerLine() {
82
return (16);
83
}
84
85
protected void encodeBufferPrefix(OutputStream o) throws IOException {
86
offset = 0;
87
pStream = new PrintStream(o);
88
}
89
90
protected void encodeLinePrefix(OutputStream o, int len) throws IOException {
91
hexDigit(pStream, (byte)((offset >>> 8) & 0xff));
92
hexDigit(pStream, (byte)(offset & 0xff));
93
pStream.print(": ");
94
currentByte = 0;
95
thisLineLength = len;
96
}
97
98
protected void encodeAtom(OutputStream o, byte buf[], int off, int len) throws IOException {
99
thisLine[currentByte] = buf[off];
100
hexDigit(pStream, buf[off]);
101
pStream.print(" ");
102
currentByte++;
103
if (currentByte == 8)
104
pStream.print(" ");
105
}
106
107
protected void encodeLineSuffix(OutputStream o) throws IOException {
108
if (thisLineLength < 16) {
109
for (int i = thisLineLength; i < 16; i++) {
110
pStream.print(" ");
111
if (i == 7)
112
pStream.print(" ");
113
}
114
}
115
pStream.print(" ");
116
for (int i = 0; i < thisLineLength; i++) {
117
if ((thisLine[i] < ' ') || (thisLine[i] > 'z')) {
118
pStream.print(".");
119
} else {
120
pStream.write(thisLine[i]);
121
}
122
}
123
pStream.println();
124
offset += thisLineLength;
125
}
126
127
/** Stream that understands "printing" */
128
protected PrintStream pStream;
129
130
/**
131
* This method works around the bizarre semantics of BufferedInputStream's
132
* read method.
133
*/
134
protected int readFully(InputStream in, byte buffer[])
135
throws java.io.IOException {
136
for (int i = 0; i < buffer.length; i++) {
137
int q = in.read();
138
if (q == -1)
139
return i;
140
buffer[i] = (byte)q;
141
}
142
return buffer.length;
143
}
144
145
/**
146
* Encode bytes from the input stream, and write them as text characters
147
* to the output stream. This method will run until it exhausts the
148
* input stream, but does not print the line suffix for a final
149
* line that is shorter than bytesPerLine().
150
*/
151
public void encode(InputStream inStream, OutputStream outStream)
152
throws IOException
153
{
154
int j;
155
int numBytes;
156
byte tmpbuffer[] = new byte[bytesPerLine()];
157
158
encodeBufferPrefix(outStream);
159
160
while (true) {
161
numBytes = readFully(inStream, tmpbuffer);
162
if (numBytes == 0) {
163
break;
164
}
165
encodeLinePrefix(outStream, numBytes);
166
for (j = 0; j < numBytes; j += bytesPerAtom()) {
167
168
if ((j + bytesPerAtom()) <= numBytes) {
169
encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
170
} else {
171
encodeAtom(outStream, tmpbuffer, j, (numBytes)- j);
172
}
173
}
174
if (numBytes < bytesPerLine()) {
175
break;
176
} else {
177
encodeLineSuffix(outStream);
178
}
179
}
180
}
181
182
/**
183
* A 'streamless' version of encode that simply takes a buffer of
184
* bytes and returns a string containing the encoded buffer.
185
*/
186
public String encode(byte aBuffer[]) {
187
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
188
ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
189
try {
190
encode(inStream, outStream);
191
// explicit ascii->unicode conversion
192
return outStream.toString(ISO_8859_1);
193
} catch (IOException ignore) {
194
// This should never happen.
195
throw new Error("CharacterEncoder.encode internal error");
196
}
197
}
198
199
/**
200
* Return a byte array from the remaining bytes in this ByteBuffer.
201
* <P>
202
* The ByteBuffer's position will be advanced to ByteBuffer's limit.
203
* <P>
204
* To avoid an extra copy, the implementation will attempt to return the
205
* byte array backing the ByteBuffer. If this is not possible, a
206
* new byte array will be created.
207
*/
208
private byte [] getBytes(ByteBuffer bb) {
209
/*
210
* This should never return a BufferOverflowException, as we're
211
* careful to allocate just the right amount.
212
*/
213
byte [] buf = null;
214
215
/*
216
* If it has a usable backing byte buffer, use it. Use only
217
* if the array exactly represents the current ByteBuffer.
218
*/
219
if (bb.hasArray()) {
220
byte [] tmp = bb.array();
221
if ((tmp.length == bb.capacity()) &&
222
(tmp.length == bb.remaining())) {
223
buf = tmp;
224
bb.position(bb.limit());
225
}
226
}
227
228
if (buf == null) {
229
/*
230
* This class doesn't have a concept of encode(buf, len, off),
231
* so if we have a partial buffer, we must reallocate
232
* space.
233
*/
234
buf = new byte[bb.remaining()];
235
236
/*
237
* position() automatically updated
238
*/
239
bb.get(buf);
240
}
241
242
return buf;
243
}
244
245
/**
246
* A 'streamless' version of encode that simply takes a ByteBuffer
247
* and returns a string containing the encoded buffer.
248
* <P>
249
* The ByteBuffer's position will be advanced to ByteBuffer's limit.
250
*/
251
public String encode(ByteBuffer aBuffer) {
252
byte [] buf = getBytes(aBuffer);
253
return encode(buf);
254
}
255
256
/**
257
* Encode bytes from the input stream, and write them as text characters
258
* to the output stream. This method will run until it exhausts the
259
* input stream. It differs from encode in that it will add the
260
* line at the end of a final line that is shorter than bytesPerLine().
261
*/
262
public void encodeBuffer(InputStream inStream, OutputStream outStream)
263
throws IOException
264
{
265
int j;
266
int numBytes;
267
byte tmpbuffer[] = new byte[bytesPerLine()];
268
269
encodeBufferPrefix(outStream);
270
271
while (true) {
272
numBytes = readFully(inStream, tmpbuffer);
273
if (numBytes == 0) {
274
break;
275
}
276
encodeLinePrefix(outStream, numBytes);
277
for (j = 0; j < numBytes; j += bytesPerAtom()) {
278
if ((j + bytesPerAtom()) <= numBytes) {
279
encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
280
} else {
281
encodeAtom(outStream, tmpbuffer, j, (numBytes)- j);
282
}
283
}
284
encodeLineSuffix(outStream);
285
if (numBytes < bytesPerLine()) {
286
break;
287
}
288
}
289
}
290
291
/**
292
* Encode the buffer in <i>aBuffer</i> and write the encoded
293
* result to the OutputStream <i>aStream</i>.
294
*/
295
public void encodeBuffer(byte aBuffer[], OutputStream aStream)
296
throws IOException
297
{
298
ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
299
encodeBuffer(inStream, aStream);
300
}
301
302
/**
303
* A 'streamless' version of encode that simply takes a buffer of
304
* bytes and returns a string containing the encoded buffer.
305
*/
306
public String encodeBuffer(byte aBuffer[]) {
307
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
308
ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
309
try {
310
encodeBuffer(inStream, outStream);
311
} catch (Exception IOException) {
312
// This should never happen.
313
throw new Error("CharacterEncoder.encodeBuffer internal error");
314
}
315
return (outStream.toString());
316
}
317
318
/**
319
* Encode the <i>aBuffer</i> ByteBuffer and write the encoded
320
* result to the OutputStream <i>aStream</i>.
321
* <P>
322
* The ByteBuffer's position will be advanced to ByteBuffer's limit.
323
*/
324
public void encodeBuffer(ByteBuffer aBuffer, OutputStream aStream)
325
throws IOException
326
{
327
byte [] buf = getBytes(aBuffer);
328
encodeBuffer(buf, aStream);
329
}
330
331
}
332
333