Reputation: 542
I have a byte array:
[11, 10, 17, 05, 00, 0a, 01, 02]
and a class:
class abc{
short var1; // [11, 10]
int var2; // [17, 05, 00, 0a]
byte var3; // [01]
byte var4; // [02]
}
In python there is a lib ctypes where you can provide a byte array and it will encode it to a object of a class (definitely structure needs to be defined before hand).
I am looking something similar in java, basically what I am looking for a method which can encode and decode byte array.
[11, 10, 17, 05, 00, 0a, 01, 02] => (some method) => object abc: abc.getVar3() // value of var3 needs to be 1 as per above structure.
also object abc => (some method) => [11, 10, 17, 05, 00, 0a, 01, 02]
.
Only solution I can think of is lots of if else statement is there any better way to do it.
I have checked this answer it serialises entire class as byte object but I only want to encode data, basically inject data in object and also retrieve data from object in byte array.
Upvotes: 0
Views: 1484
Reputation: 1115
Assuming you have looked at Serialization Utils from Apache Commons, you could understand that there should be some sort of class based object to be an input for any serialization algorithm.
However you want to avoid having a separate dedicated class to store and retrieve data (if I'm wrong clarify me). One possible workaround is to use a built-in class in java to encapsulate the data for you.
For example you could put your data fields in a List (ArrayList
) or even better a Map (HashMap
). Then you could serialize the map object so that it can be passed around. The good thing is these classes are already built into java so you don't need to create a separate class just for the sake of serialization.
Here is a sample example code:
import org.apache.commons.lang3.SerializationUtils;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
class Abc {
short var1; // [11, 10]
int var2; // [17, 05, 00, 0a]
byte var3; // [01]
byte var4; // [02]
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
map.put("var1", var1);
map.put("var2", var2);
map.put("var3", var3);
map.put("var4", var4);
return map;
}
public byte[] serializeMap() {
return SerializationUtils.serialize((Serializable) toMap());
}
public Map<String, Object> deSerializeMap(byte[] serializedObject) {
return SerializationUtils.deserialize(serializedObject);
}
public void setParams(Map<String, Object> deSerializedObject) {
this.var1 = (short) deSerializedObject.get("var1");
this.var2 = (int) deSerializedObject.get("var2");
this.var3 = (byte) deSerializedObject.get("var3");
this.var4 = (byte) deSerializedObject.get("var4");
}
}
public class Test2 {
public static void main(String[] args) {
Abc obj = new Abc();
obj.var1 = 10000;
obj.var2 = 500000;
obj.var3 = 2;
obj.var4 = 30;
Abc newObj = new Abc();
newObj.setParams(newObj.deSerializeMap(obj.serializeMap()));
System.out.printf("var1: %s\nvar2: %s\nvar3: %s\nvar4: %s\n", newObj.var1, newObj.var2, newObj.var3, newObj.var4);
}
}
As you can see here, I use obj
to create the values, then serialize it and newObj
to deserialize and assign back to the variable.
obj
could be belong to one class and you could serialize and send the values through network and can deserialize them on another object. This is possible because the HashMap is already built into Java.
Good thing here is that you don't need to have same class in both places. As long as both classes have above variables (variables don't even have to have a same name either, as long as type matches, this will work), you could implement this solution.
Upvotes: 0
Reputation: 1097
There's several ways to do that. Here's a simple one:
byte[] values = [11, 10, 17, 05, 00, 0a, 01, 02]; //WARNING: update 0a to the right value in java
The class definition (class name start with uppercase in java):
class Abc{
short[] var1; // [11, 10]
int[] var2; // [17, 05, 00, 0a]
byte var3; // [01]
byte var4; // [02]
public Abc(byte[] values){
var1 = new short[]{(short)values[0],(short)values[1]};
var2 = new int[]{(int)values[2],(int)values[3],(int)values[4],(int)values[5]};
var3 = values[6];
var4 = values[7];
}
public byte[] getBytes(){
return new byte[]{ (byte)var1[0], (byte)var1[1], (byte)var2[0],(byte)var2[1], (byte)var2[2], (byte)var2[3], var3, var4};
}
}
So to create a new object (objects are lowercase):
Abc abc = new Abc(values);
byte[] result = abc.getBytes();
Upvotes: 0
Reputation: 15706
DataInputStream allows you to read primitives from an input stream. Look out for following methods:
readShort()
readInt()
readByte()
Example code:
byte[] data = {0x11, 0x10, 0x17, 0x05, 0x00, 0x0a, 0x01, 0x02};
try (DataInputStream in = new DataInputStream(new ByteArrayInputStream(data))) {
abc value = new abc();
value.var1 = in.readShort();
value.var2 = in.readInt();
value.var3 = in.readByte();
value.var4 = in.readByte();
}
Upvotes: 1