Skip to content

Instantly share code, notes, and snippets.

@acmi
Created October 4, 2014 19:07
Show Gist options
  • Save acmi/b2937e2a12e37027ec79 to your computer and use it in GitHub Desktop.
Save acmi/b2937e2a12e37027ec79 to your computer and use it in GitHub Desktop.
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.stage.Stage;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
public class IndexConverter extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
final TextField index = new TextField();
final TextField integer = new TextField();
index.focusedProperty().addListener(new ChangeListener<Boolean>() {
ChangeListener<String> indexListener = new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
try {
byte[] bytes = parseBytes(newValue.replaceAll("\\s", ""));
ByteBuffer buffer = ByteBuffer.wrap(bytes);
int result = getCompactInt(buffer);
if (buffer.position() != buffer.limit())
throw new Exception();
integer.setText(String.valueOf(result));
} catch (Exception e) {
integer.setText("");
}
}
};
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue)
index.textProperty().addListener(indexListener);
else
index.textProperty().removeListener(indexListener);
}
});
integer.focusedProperty().addListener(new ChangeListener<Boolean>() {
ChangeListener<String> integerListener = new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
try {
int v = Integer.parseInt(newValue);
byte[] bytes = compactIntToByteArray(v);
StringBuilder sb = new StringBuilder(String.format("%02X", bytes[0]));
for (int i = 1; i < bytes.length; i++)
sb.append(String.format(" %02X", bytes[i]));
index.setText(sb.toString());
} catch (Exception e) {
index.setText("");
}
}
};
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue)
integer.textProperty().addListener(integerListener);
else
integer.textProperty().removeListener(integerListener);
}
});
GridPane pane = new GridPane();
pane.add(new Label("Index"), 0, 0);
pane.add(new Label("Integer"), 0, 1);
pane.add(index, 1, 0);
pane.add(integer, 1, 1);
pane.setPadding(new Insets(2., 2., 2., 2.));
pane.setHgap(2.);
pane.setVgap(2.);
pane.getColumnConstraints().addAll(
new ColumnConstraints(Region.USE_PREF_SIZE, Region.USE_COMPUTED_SIZE, Region.USE_PREF_SIZE, Priority.NEVER, HPos.LEFT, true),
new ColumnConstraints(0.0, Region.USE_COMPUTED_SIZE, Double.MAX_VALUE, Priority.ALWAYS, HPos.LEFT, true));
primaryStage.setTitle(getClass().getSimpleName());
primaryStage.setScene(new Scene(pane));
primaryStage.show();
}
public static byte[] parseBytes(String text) throws NumberFormatException {
byte[] bytes = new byte[(text.length() + 1) / 2];
for (int i = bytes.length - 1; i >= 0; i--) {
int ind = Math.max(0, text.length() - 2);
bytes[i] = (byte) Integer.parseInt(text.substring(ind), 16);
text = text.substring(0, ind);
}
return bytes;
}
public static int getCompactInt(ByteBuffer input) throws BufferUnderflowException {
int output = 0;
boolean signed = false;
for (int i = 0; i < 5; i++) {
int x = input.get() & 0xff;
if (i == 0) {
if ((x & 0x80) > 0)
signed = true;
output |= (x & 0x3F);
if ((x & 0x40) == 0)
break;
} else if (i == 4) {
output |= (x & 0xF) << (6 + (3 * 7));
} else {
output |= (x & 0x7F) << (6 + ((i - 1) * 7));
if ((x & 0x80) == 0)
break;
}
}
if (signed)
output *= -1;
return output;
}
public static byte[] compactIntToByteArray(int v) {
boolean negative = v < 0;
v = Math.abs(v);
int[] bytes = new int[]{
(v) & 0b00111111,
(v >> 6) & 0b01111111,
(v >> 6 + 7) & 0b01111111,
(v >> 6 + 7 + 7) & 0b01111111,
(v >> 6 + 7 + 7 + 7) & 0b01111111
};
if (negative) bytes[0] |= 0b10000000;
int size = 5;
for (int i = 4; i > 0; i--) {
if (bytes[i] != 0)
break;
size--;
}
byte[] res = new byte[size];
for (int i = 0; i < size; i++) {
if (i != size - 1)
bytes[i] |= i == 0 ? 0b01000000 : 0b10000000;
res[i] = (byte) bytes[i];
}
return res;
}
public static void main(String[] args) {
launch(args);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment