Skip to content

Commit d7b5da3

Browse files
committed
GH-407 display byte[] arrays similarly to 'hexdump -C'
1 parent dfb2fb0 commit d7b5da3

File tree

1 file changed

+50
-1
lines changed
  • visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/basic

1 file changed

+50
-1
lines changed

visualvm/libs.profiler/profiler.heapwalker/src/org/graalvm/visualvm/lib/profiler/heapwalk/details/basic/ArrayValueView.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,16 @@
3030
import java.awt.Container;
3131
import java.awt.Cursor;
3232
import java.awt.Dimension;
33+
import java.awt.Font;
3334
import java.awt.GridBagConstraints;
3435
import java.awt.GridBagLayout;
3536
import java.awt.Insets;
3637
import java.awt.Rectangle;
3738
import java.awt.event.ActionEvent;
3839
import java.awt.event.ActionListener;
40+
import java.util.Arrays;
3941
import java.util.List;
42+
import java.util.regex.Pattern;
4043
import javax.swing.BorderFactory;
4144
import javax.swing.JButton;
4245
import javax.swing.JLabel;
@@ -145,6 +148,10 @@ public void run() {
145148
add(l, BorderLayout.NORTH);
146149

147150
view = new JTextArea();
151+
if (bytearray) {
152+
Font defaultFont = view.getFont();
153+
view.setFont(new Font(Font.MONOSPACED, Font.PLAIN, defaultFont.getSize()));
154+
}
148155
l.setLabelFor(view);
149156
view.setEditable(false);
150157
view.setLineWrap(true);
@@ -227,6 +234,7 @@ public void run() {
227234

228235
private String getString(boolean preview) {
229236
if (values == null) return ""; // NOI18N
237+
if (bytearray) return getHexDump(preview);
230238
StringDecoder decoder = new StringDecoder(heap, coder, values);
231239
int valuesCount = count < 0 ? decoder.getStringLength() - offset : count;
232240
int separatorLength = separator == null ? 0 : separator.length();
@@ -245,7 +253,48 @@ private String getString(boolean preview) {
245253
return value.toString();
246254
}
247255

248-
256+
private static final int LINE_LEN = 0x10;
257+
258+
private String getHexDump(boolean preview) {
259+
StringBuilder value = new StringBuilder();
260+
StringBuilder chars = new StringBuilder();
261+
int lastValue = count - 1;
262+
for (int i = 0; i <= lastValue; i++) {
263+
if (i%LINE_LEN == 0) {
264+
if (i != 0) {
265+
value.append(getPrintableChars(chars));
266+
value.append("\n");
267+
chars = new StringBuilder();
268+
}
269+
if (preview && i >= MAX_PREVIEW_LENGTH) {
270+
truncated = true;
271+
break;
272+
}
273+
value.append(String.format("%04X ", i));
274+
}
275+
byte val = Byte.parseByte(values.get(i));
276+
value.append(String.format("%02X ", val));
277+
chars.append((char)val);
278+
}
279+
if (chars.length() > 0) {
280+
char[] spaces = new char[(LINE_LEN-chars.length())*3];
281+
Arrays.fill(spaces, ' ');
282+
value.append(spaces);
283+
value.append(getPrintableChars(chars));
284+
}
285+
return value.toString();
286+
}
287+
288+
private static final Pattern REGEXP = Pattern.compile("\\P{Print}");
289+
290+
private String getPrintableChars(StringBuilder chars) {
291+
StringBuilder val = new StringBuilder();
292+
val.append(" |");
293+
val.append(REGEXP.matcher(chars.toString()).replaceAll("."));
294+
val.append("|");
295+
return val.toString();
296+
}
297+
249298
public Dimension getPreferredScrollableViewportSize() {
250299
return null;
251300
}

0 commit comments

Comments
 (0)