package Javonet::Core::Protocol::CommandDeserializer;
use strict;
use warnings;
use Moose;
use lib 'lib';
use aliased 'Javonet::Sdk::Core::PerlCommand' => 'PerlCommand';
use aliased 'Javonet::Sdk::Core::Type' => 'Type', qw(get_type);
use aliased 'Javonet::Core::Protocol::TypeDeserializer' => 'TypeDeserializer';
use Exporter qw(import);
our @EXPORT = qw(new isAtEnd decode readObject readCommand readCommandRecursively readString readInt readBool readFloat readByte readChar readLongLong readDouble readUnsignedLongLong readUnsignedInt readUndef);
our $position = 0;
our @buffer = [];
our $command;
sub new {
my ($self, $array_ref) = @_;
@buffer = @$array_ref;
$command = PerlCommand->new(runtime => $buffer[0],
command_type => $buffer[10], payload => []);
$position = 11;
return $self;
}
sub isAtEnd {
my $length = @buffer;
return $position == $length;
}
sub decode {
while (!isAtEnd()) {
$command = $command->addArgumentToPayload([ readObject($buffer[$position]) ]);
}
return $command;
}
sub readObject {
my $type_num = $_[0];
if ($type_num == Type->get_type('Command')) {
return readCommand();
}
elsif ($type_num == Type->get_type('JavonetString')) {
return readString();
}
elsif ($type_num == Type->get_type('JavonetInteger')) {
return readInt();
}
elsif ($type_num == Type->get_type('JavonetBool')) {
return readBool();
}
elsif ($type_num == Type->get_type('JavonetFloat')) {
return readFloat();
}
elsif ($type_num == Type->get_type('JavonetByte')) {
return readByte();
}
elsif ($type_num == Type->get_type('JavonetChar')) {
return readChar();
}
elsif ($type_num == Type->get_type('JavonetLongLong')) {
return readLongLong();
}
elsif ($type_num == Type->get_type('JavonetDouble')) {
return readDouble();
}
elsif ($type_num == Type->get_type('JavonetUnsignedLongLong')) {
return readUnsignedLongLong();
}
elsif ($type_num == Type->get_type('JavonetUnsignedInteger')) {
return readUnsignedInt();
}
elsif ($type_num == Type->get_type('JavonetNull')) {
return readUndef();
}
else {
die "Type is not supported: $type_num";
}
}
sub readCommand {
my $p = $position;
my @int_buffer = @buffer[$p + 1 .. $p + 4];
my $numberOfArgumentInPayload = TypeDeserializer->deserializeInt(\@int_buffer);
my $runtime = $buffer[$p + 5];
my $commandType = $buffer[$p + 6];
$position += 7;
my $returnCommand = PerlCommand->new(runtime => $runtime, command_type => $commandType);
return readCommandRecursively($numberOfArgumentInPayload, $returnCommand);
}
sub readCommandRecursively {
my $numberOfArgumentInPayloadLeft = $_[0];
my $cmd = $_[1];
if ($numberOfArgumentInPayloadLeft == 0) {
return $cmd;
}
else {
my $p = $position;
my @int_buffer = @buffer[$p + 1 .. $p + 4];
my $argSize = TypeDeserializer->deserializeInt(\@int_buffer);
$cmd = $cmd->addArgumentToPayload([ readObject($buffer[$p]) ]);
return readCommandRecursively($numberOfArgumentInPayloadLeft - 1, $cmd);
}
}
sub readString {
my $p = $position;
my $string_encoding_mode = $buffer[$p + 1];
my @int_buffer = @buffer[$p + 2 .. $p + 5];
my $size = TypeDeserializer->deserializeInt(\@int_buffer);
$position += 6;
$p = $position;
$position += $size;
my @string_buffer = @buffer[$p .. $p + $size - 1];
my $decodedString = TypeDeserializer->deserializeString($string_encoding_mode, \@string_buffer);
return $decodedString
}
sub readInt {
$position += 2;
my $p = $position;
$position += 4;
my @int_buffer = @buffer[$p .. $p + 3];
return TypeDeserializer->deserializeInt(\@int_buffer);
}
sub readBool {
$position += 2;
my $p = $position;
$position += 1;
my $bool_buffer = $buffer[$p];
return TypeDeserializer->deserializeBool($bool_buffer);
}
sub readFloat {
$position += 2;
my $p = $position;
$position += 4;
my @float_buffer = @buffer[$p .. $p + 3];
return TypeDeserializer->deserializeFloat(\@float_buffer);
}
sub readByte {
$position += 2;
my $p = $position;
$position += 1;
my $byte_buffer = $buffer[$p];
return TypeDeserializer->deserializeByte($byte_buffer);
}
sub readChar {
$position += 2;
my $p = $position;
$position += 1;
my $char_buffer = $buffer[$p];
return TypeDeserializer->deserializeChar($char_buffer);
}
sub readLongLong {
$position += 2;
my $p = $position;
$position += 8;
my @longlong_buffer = @buffer[$p .. $p + 7];
return TypeDeserializer->deserializeLongLong(\@longlong_buffer);
}
sub readDouble {
$position += 2;
my $p = $position;
$position += 8;
my @double_buffer = @buffer[$p .. $p + 7];
return TypeDeserializer->deserializeDouble(\@double_buffer);
}
sub readUnsignedLongLong {
$position += 2;
my $p = $position;
$position += 8;
my @ulonglong_buffer = @buffer[$p .. $p + 7];
return TypeDeserializer->deserializeULongLong(\@ulonglong_buffer);
}
sub readUnsignedInt {
$position += 2;
my $p = $position;
$position += 4;
my @uint_buffer = @buffer[$p .. $p + 3];
return TypeDeserializer->deserializeUInt(\@uint_buffer);
}
sub readUndef {
$position += 2;
my $p = $position;
$position += 1;
my $undef_buffer = $buffer[$p];
return TypeDeserializer->deserializeUndef($undef_buffer);
}
no Moose;
1;