com.javonet.core.protocol.CommandSerializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javonet-java-sdk Show documentation
Show all versions of javonet-java-sdk Show documentation
Javonet allows you to reference and use modules or packages written in (Java/Kotlin/Groovy/Clojure, C#/VB.NET, Ruby, Perl, Python, JavaScript/TypeScript) like they were created in your technology.
It works on Linux/Windows and MacOS for applications created in JVM, CLR/Netcore, Perl, Python, Ruby, NodeJS, C++ or GoLang and gives you unparalleled freedom and flexibility with native performance in building your mixed-technologies products.
Let it be accessing best AI or cryptography libraries, devices SDKs, legacy client modules, internal custom packages or anything from public repositories available on NPM, Nuget, PyPI, Maven/Gradle, RubyGems or GitHub. Get free from programming languages barriers today!
For more information check out our guides at https://www.javonet.com/guides/v2/
package com.javonet.core.protocol;
import com.javonet.utils.Command;
import com.javonet.utils.RuntimeName;
import com.javonet.utils.ConnectionType;
import com.javonet.utils.TcpConnectionData;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
import java.util.Deque;
public class CommandSerializer {
private ByteBuffer byteBuffer = ByteBuffer.allocate(0);
private Deque deque = new ArrayDeque<>();
public byte[] serialize(Command root, ConnectionType connectionType, TcpConnectionData tcpConnectionData) {
byteBuffer = ByteBuffer.allocate(0);
deque.push(root);
insertIntoBuffer(new byte[]{
(byte) root.getRuntimeName().ordinal(),
(byte) 0
});
serializeTcp(connectionType, tcpConnectionData);
insertIntoBuffer(new byte[]{
(byte) RuntimeName.Jvm.ordinal(),
(byte) root.getCommandType().ordinal()
});
return serializeRecursively(deque);
}
private void serializeTcp(ConnectionType connectionType, TcpConnectionData tcpConnectionData) {
insertIntoBuffer(new byte[]{(byte) connectionType.ordinal()});
if (connectionType == ConnectionType.TCP) {
insertIntoBuffer(tcpConnectionData.getAddressBytes());
insertIntoBuffer(tcpConnectionData.getPortBytes());
} else {
insertIntoBuffer(new byte[]{0,0,0,0,0,0});
}
}
private byte[] serializeRecursively(Deque deque) {
if (deque.isEmpty()) return byteBuffer.array();
// retrieve command from top of the stack and put it without last arg back to deque
Command cmd = deque.pop();
deque.push(cmd.dropFirstPayloadArg());
if (cmd.getPayload().length > 0 && cmd.getPayload()[0] != null) {
Class targetClass = cmd.getPayload()[0].getClass();
if (targetClass == Command.class) {
Command innerCommand = (Command) cmd.getPayload()[0];
insertIntoBuffer(TypeSerializer.serializeCommand(innerCommand));
// adding to stack inner command to be processed on next recursion
deque.push(innerCommand);
} else if (targetClass.isArray()) {
for (int i = 0; i < ((Object[]) cmd.getPayload()[0]).length; i++) {
byte[] result = TypeSerializer.serializePrimitive(((Object[]) cmd.getPayload()[0])[i]);
insertIntoBuffer(result);
}
} else {
// else process primitive payload argument
byte[] result = TypeSerializer.serializePrimitive(cmd.getPayload()[0]);
insertIntoBuffer(result);
}
} else {
// clear command without payload from top of the stack
deque.pop();
}
return this.serializeRecursively(deque);
}
private void insertIntoBuffer(byte[] arg) {
ByteBuffer newByteBuffer = ByteBuffer.allocate(arg.length + this.byteBuffer.limit());
newByteBuffer.put(this.byteBuffer.array());
newByteBuffer.put(arg);
this.byteBuffer = newByteBuffer;
}
}