Skip to content

Commit 9468380

Browse files
committed
Release 0.1.6
1 parent e5a7cde commit 9468380

4 files changed

Lines changed: 209 additions & 32 deletions

File tree

changes.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
0.1.6
2-
- Added "Show as hex" action for debugger data
1+
0.1.6 (2018-03-05)
2+
- Added "Show as hex" action for debugger (native types and native arrays only)
33
- Show "Document changed" dialog on window close
44
- Fixed Unknown property name: 'modified' (issue #3)
55

resources/META-INF/plugin.xml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<idea-plugin version="2">
22
<id>org.exbin.deltahex.intellij</id>
33
<name>DeltaHex Editor</name>
4-
<version>0.1.6-SNAPSHOT</version>
4+
<version>0.1.6</version>
55
<vendor email="hajdam@users.sf.net" url="http://deltahex.exbin.org">ExBin Project</vendor>
66

77
<description><![CDATA[
@@ -24,11 +24,9 @@
2424
]]></description>
2525

2626
<change-notes><![CDATA[
27-
<ul><li>Values panel made editable</li>
28-
<li>Byte order support for floating point numbers in values panel</li>
29-
<li>Added thread for values panel updating</li>
30-
<li>Fixed files closing on window closing</li>
31-
<li>Fixed clipboard charset translation</li></ul>
27+
<ul><li>Added "Show as hex" action for debugger (native types and native arrays only)</li>
28+
<li>Show "Document changed" dialog on window close</li>
29+
<li>Fixed Unknown property name: 'modified' (issue #3)</li></ul>
3230
]]>
3331
</change-notes>
3432

@@ -77,11 +75,6 @@
7775
<add-to-group group-id="XDebugger.Evaluation.Dialog.Tree.Popup" anchor="last"/>
7876
<add-to-group group-id="XDebugger.Inspect.Tree.Popup" anchor="last"/>
7977
</group>
80-
81-
<!-- <group>
82-
<reference id="DeltaHexEditor.OpenAsHexAction"/>
83-
<add-to-group group-id="EditorPopupMenu" relative-to-action="EditorDelete" anchor="after"/>
84-
</group> -->
8578
</actions>
8679

8780
</idea-plugin>

src/org/exbin/deltahex/intellij/DebugViewHexAction.java

Lines changed: 139 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,26 @@
2929
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
3030
import com.intellij.xdebugger.impl.ui.tree.actions.XFetchValueActionBase;
3131
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
32-
import com.sun.jdi.ArrayReference;
33-
import com.sun.jdi.ArrayType;
32+
import com.sun.jdi.*;
3433
import org.exbin.deltahex.intellij.debug.*;
3534
import org.exbin.deltahex.intellij.panel.DebugViewPanel;
35+
import org.exbin.deltahex.intellij.panel.ValuesPanel;
3636
import org.exbin.utils.binary_data.BinaryData;
3737
import org.exbin.utils.binary_data.ByteArrayData;
3838
import org.jetbrains.annotations.NotNull;
3939
import org.jetbrains.annotations.Nullable;
4040

4141
import javax.swing.*;
42+
import java.math.BigInteger;
43+
import java.nio.ByteBuffer;
4244
import java.nio.charset.Charset;
4345
import java.util.List;
4446

4547
/**
4648
* Show debugger value in hexadecimal editor action.
4749
*
4850
* @author ExBin Project (http://exbin.org)
49-
* @version 0.1.3 2017/03/20
51+
* @version 0.1.6 2018/03/05
5052
*/
5153
public class DebugViewHexAction extends XFetchValueActionBase {
5254

@@ -57,7 +59,7 @@ protected void handle(Project project, String value, XDebuggerTree tree) {
5759
@NotNull
5860
@Override
5961
protected ValueCollector createCollector(@NotNull AnActionEvent e) {
60-
XValueNodeImpl node = getStringNode(e);
62+
XValueNodeImpl node = getDataNode(e);
6163
return new ValueCollector(XDebuggerTree.getTree(e.getDataContext())) {
6264
DataDialog dialog = null;
6365

@@ -75,30 +77,46 @@ public void handleInCollector(Project project, String value, XDebuggerTree tree)
7577
}
7678

7779
@Override
78-
public void update(@NotNull AnActionEvent e) {
79-
super.update(e);
80-
if (getStringNode(e) != null) {
81-
e.getPresentation().setText("View Hex");
82-
// e.getPresentation().setIcon("/images/icon.png");
80+
public void update(@NotNull AnActionEvent event) {
81+
super.update(event);
82+
if (getDataNode(event) != null) {
83+
event.getPresentation().setText("View Hex");
8384
}
8485
}
8586

86-
private static XValueNodeImpl getStringNode(@NotNull AnActionEvent e) {
87-
List<XValueNodeImpl> selectedNodes = XDebuggerTreeActionBase.getSelectedNodes(e.getDataContext());
87+
private static XValueNodeImpl getDataNode(@NotNull AnActionEvent event) {
88+
List<XValueNodeImpl> selectedNodes = XDebuggerTreeActionBase.getSelectedNodes(event.getDataContext());
8889
if (selectedNodes.size() == 1) {
8990
XValueNodeImpl node = selectedNodes.get(0);
9091
XValue container = node.getValueContainer();
9192
if (container instanceof JavaValue && container.getModifier() != null) {
9293
ValueDescriptorImpl descriptor = ((JavaValue) container).getDescriptor();
93-
if (descriptor.isString() || descriptor.isArray()) {
94+
if (descriptor.isString() || descriptor.isArray() || descriptor.isPrimitive() || isBasicType(descriptor)) {
9495
return node;
9596
}
9697
}
9798
}
9899
return null;
99100
}
100101

102+
private static boolean isBasicType(ValueDescriptorImpl descriptor) {
103+
final String type = descriptor.getDeclaredType();
104+
return CommonClassNames.JAVA_LANG_BYTE.equals(type)
105+
|| CommonClassNames.JAVA_LANG_SHORT.equals(type)
106+
|| CommonClassNames.JAVA_LANG_SHORT.equals(type)
107+
|| CommonClassNames.JAVA_LANG_INTEGER.equals(type)
108+
|| CommonClassNames.JAVA_LANG_LONG.equals(type)
109+
|| CommonClassNames.JAVA_LANG_FLOAT.equals(type)
110+
|| CommonClassNames.JAVA_LANG_DOUBLE.equals(type)
111+
|| CommonClassNames.JAVA_LANG_CHARACTER.equals(type);
112+
}
113+
101114
private static class DataDialog extends DialogWrapper {
115+
116+
private final byte[] valuesCache = new byte[8];
117+
private final ByteBuffer byteBuffer = ByteBuffer.wrap(valuesCache);
118+
119+
102120
private final DebugViewPanel viewPanel;
103121
private final XValueNodeImpl myDataNode;
104122

@@ -113,11 +131,93 @@ private DataDialog(Project project, @Nullable String initialValue, @Nullable XVa
113131

114132
viewPanel = new DebugViewPanel();
115133

134+
BinaryData data = null;
135+
116136
if (myDataNode != null) {
117137
XValue container = myDataNode.getValueContainer();
118138
ValueDescriptorImpl descriptor = ((JavaValue) container).getDescriptor();
119-
BinaryData data = null;
120-
if (descriptor.isArray()) {
139+
if (descriptor.isPrimitive() || isBasicType(descriptor) || !descriptor.isNull()) {
140+
final String type = descriptor.getDeclaredType();
141+
switch (type) {
142+
case CommonClassNames.JAVA_LANG_BYTE:
143+
case "byte": {
144+
ByteValue value = (ByteValue) getPrimitiveValue(descriptor);
145+
byte[] byteArray = new byte[1];
146+
byteArray[0] = value.value();
147+
data = new ByteArrayData(byteArray);
148+
break;
149+
}
150+
case CommonClassNames.JAVA_LANG_SHORT:
151+
case "short": {
152+
ShortValue valueRecord = (ShortValue) getPrimitiveValue(descriptor);
153+
byte[] byteArray = new byte[2];
154+
short value = valueRecord.value();
155+
byteArray[0] = (byte) (value >> 8);
156+
byteArray[1] = (byte) (value & 0xff);
157+
data = new ByteArrayData(byteArray);
158+
break;
159+
}
160+
case CommonClassNames.JAVA_LANG_INTEGER:
161+
case "int": {
162+
IntegerValue valueRecord = (IntegerValue) getPrimitiveValue(descriptor);
163+
byte[] byteArray = new byte[4];
164+
int value = valueRecord.value();
165+
byteArray[0] = (byte) (value >> 24);
166+
byteArray[1] = (byte) ((value >> 16) & 0xff);
167+
byteArray[2] = (byte) ((value >> 8) & 0xff);
168+
byteArray[3] = (byte) (value & 0xff);
169+
data = new ByteArrayData(byteArray);
170+
break;
171+
}
172+
case CommonClassNames.JAVA_LANG_LONG:
173+
case "long": {
174+
LongValue valueRecord = (LongValue) getPrimitiveValue(descriptor);
175+
byte[] byteArray = new byte[8];
176+
long value = valueRecord.value();
177+
BigInteger bigInteger = BigInteger.valueOf(value);
178+
for (int bit = 0; bit < 7; bit++) {
179+
BigInteger nextByte = bigInteger.and(ValuesPanel.BIG_INTEGER_BYTE_MASK);
180+
byteArray[7 - bit] = nextByte.byteValue();
181+
bigInteger = bigInteger.shiftRight(8);
182+
}
183+
data = new ByteArrayData(byteArray);
184+
break;
185+
}
186+
case CommonClassNames.JAVA_LANG_FLOAT:
187+
case "float": {
188+
FloatValue valueRecord = (FloatValue) getPrimitiveValue(descriptor);
189+
byte[] byteArray = new byte[4];
190+
float value = valueRecord.value();
191+
byteBuffer.rewind();
192+
byteBuffer.putFloat(value);
193+
System.arraycopy(valuesCache, 0, byteArray, 0, 4);
194+
data = new ByteArrayData(byteArray);
195+
break;
196+
}
197+
case CommonClassNames.JAVA_LANG_DOUBLE:
198+
case "double": {
199+
DoubleValue valueRecord = (DoubleValue) getPrimitiveValue(descriptor);
200+
byte[] byteArray = new byte[8];
201+
double value = valueRecord.value();
202+
byteBuffer.rewind();
203+
byteBuffer.putDouble(value);
204+
System.arraycopy(valuesCache, 0, byteArray, 0, 8);
205+
data = new ByteArrayData(byteArray);
206+
break;
207+
}
208+
case CommonClassNames.JAVA_LANG_CHARACTER:
209+
case "char": {
210+
CharValue valueRecord = (CharValue) getPrimitiveValue(descriptor);
211+
byte[] byteArray = new byte[2];
212+
char value = valueRecord.value();
213+
byteBuffer.rewind();
214+
byteBuffer.putChar(value);
215+
System.arraycopy(valuesCache, 0, byteArray, 0, 2);
216+
data = new ByteArrayData(byteArray);
217+
break;
218+
}
219+
}
220+
} else if (descriptor.isArray()) {
121221
final ArrayReference arrayRef = (ArrayReference) descriptor.getValue();
122222
final ArrayType type = (ArrayType) descriptor.getType();
123223
if (type != null) {
@@ -153,23 +253,43 @@ private DataDialog(Project project, @Nullable String initialValue, @Nullable XVa
153253
data = new DebugViewDataSource(new DoubleArrayPageProvider(arrayRef));
154254
break;
155255
}
156-
// TODO
256+
case CommonClassNames.JAVA_LANG_CHARACTER:
257+
case "char": {
258+
data = new DebugViewDataSource(new CharArrayPageProvider(arrayRef));
259+
break;
260+
}
157261
}
158262
}
159263
} else {
160-
data = new ByteArrayData(myDataNode.getRawValue().getBytes(Charset.defaultCharset()));
264+
String rawValue = myDataNode.getRawValue();
265+
if (rawValue != null) {
266+
data = new ByteArrayData(rawValue.getBytes(Charset.defaultCharset()));
267+
}
161268
}
269+
}
162270

163-
if (data == null) {
271+
if (data == null) {
272+
if (initialValue != null) {
273+
data = new ByteArrayData(initialValue.getBytes(Charset.defaultCharset()));
274+
} else {
164275
data = new ByteArrayData(new byte[0]);
165276
}
166-
167-
viewPanel.setData(data);
168277
}
169278

279+
viewPanel.setData(data);
280+
170281
init();
171282
}
172283

284+
private Value getPrimitiveValue(ValueDescriptorImpl descriptor) {
285+
if (descriptor.isPrimitive())
286+
return descriptor.getValue();
287+
288+
Field field = ((ObjectReference) descriptor.getValue()).referenceType().fieldByName("value");
289+
Value value = ((ObjectReference) descriptor.getValue()).getValue(field);
290+
return value;
291+
}
292+
173293
public void setText(String text) {
174294
// TODO
175295
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (C) ExBin Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.exbin.deltahex.intellij.debug;
17+
18+
import com.sun.jdi.ArrayReference;
19+
import com.sun.jdi.CharValue;
20+
import com.sun.jdi.Value;
21+
import org.exbin.deltahex.intellij.DebugViewDataSource;
22+
23+
import java.util.List;
24+
25+
/**
26+
* Character array data source for debugger view.
27+
*
28+
* @author ExBin Project (http://exbin.org)
29+
* @version 0.1.6 2018/03/05
30+
*/
31+
public class CharArrayPageProvider implements DebugViewDataSource.PageProvider {
32+
33+
private final ArrayReference arrayRef;
34+
35+
public CharArrayPageProvider(ArrayReference arrayRef) {
36+
this.arrayRef = arrayRef;
37+
}
38+
39+
@Override
40+
public byte[] getPage(long pageIndex) {
41+
int pageSize = DebugViewDataSource.PAGE_SIZE / 2;
42+
int startPos = (int) (pageIndex * pageSize);
43+
int length = pageSize;
44+
if (arrayRef.length() - startPos < pageSize) {
45+
length = arrayRef.length() - startPos;
46+
}
47+
final List<Value> values = arrayRef.getValues(startPos, length);
48+
byte[] result = new byte[length * 2];
49+
for (int i = 0; i < values.size(); i++) {
50+
Value rawValue = values.get(i);
51+
int value = (int) (rawValue instanceof CharValue ? ((CharValue) rawValue).value() : 0);
52+
53+
result[i * 2 ] = (byte) ((value >> 8) & 0xff);
54+
result[i * 2 + 1] = (byte) (value & 0xff);
55+
}
56+
57+
return result;
58+
}
59+
60+
@Override
61+
public long getDocumentSize() {
62+
return arrayRef.length() * 2;
63+
}
64+
}

0 commit comments

Comments
 (0)