File Coverage

blib/lib/App/EvalServerAdvanced/Protocol.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package App::EvalServerAdvanced::Protocol;
2 1     1   24456 use strict;
  1         4  
  1         33  
3 1     1   6 use warnings;
  1         2  
  1         35  
4              
5             our $VERSION = '0.101';
6             # ABSTRACT: Protocol abstraction for App::EvalServerAdvanced
7              
8 1     1   701 use Google::ProtocolBuffers::Dynamic;
  0            
  0            
9             use Path::Tiny qw/path/;
10             use Function::Parameters;
11              
12             use Exporter 'import';
13             our @EXPORT = qw/decode_message encode_message/;
14              
15             my $path = path(__FILE__)->parent->child("protocol.proto");
16              
17             # load_file tries to allocate >100TB of ram. Not sure why, so we'll just read it ourselves
18             my $proto = $path->slurp_raw;
19              
20             my $gpb = Google::ProtocolBuffers::Dynamic->new();
21              
22             $gpb->load_string("protocol.proto", $proto);
23              
24             $gpb->map({ pb_prefix => "messages", prefix => "App::EvalServerAdvanced::Protocol", options => {accessor_style => 'single_accessor'} });
25              
26             fun encode_message($type, $obj) {
27             my $message = App::EvalServerAdvanced::Protocol::Packet->encode({$type => $obj});
28              
29             # 8 byte header, 0x0000_0000 0x1234_5678
30             # first 4 bytes are reserved for future fuckery, last 4 are length of the message in octets
31             my $header = pack "NN", 0, length($message);
32             return ($header . $message);
33             };
34              
35             fun decode_message($buffer) {
36             return (0, undef, undef) if length $buffer < 8; # can't have a message without a header
37              
38             my $header = substr($buffer, 0, 8); # grab the header
39             my ($reserved, $length) = unpack("NN", $header);
40              
41             die "Undecodable header" if ($reserved != 0);
42            
43             # Packet isn't ready yet
44             return (0, undef, undef) if (length($buffer) - 8 < $length);
45              
46             my $message_bytes = substr($buffer, 8, $length);
47             substr($buffer, 0, $length+8, "");
48              
49             my $message = App::EvalServerAdvanced::Protocol::Packet->decode($message_bytes);
50             my ($k) = keys %$message;
51              
52             die "Undecodable message" unless ($k);
53              
54             return (1, $message->$k, $buffer);
55             };
56              
57             1;