-
Notifications
You must be signed in to change notification settings - Fork 0
/
test-message.pl
executable file
·75 lines (58 loc) · 1.74 KB
/
test-message.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/perl -w
use strict;
use lib '.';
use WireFormat qw/ :all /;
use IO::Scalar;
use Data::Dumper;
my $scalar = '';
my $handle = IO::Scalar->new(\$scalar);
write_tag($handle, 1, 0);
write_varint($handle, 10_000_000);
$handle->seek(0, 0);
sub parse_message_from_handle
{
my ($handle, $max_bytes) = @_;
my $obj = [];
my $total_bytes_read = 0;
while (!$handle->eof() && (! defined($max_bytes) || $max_bytes > $total_bytes_read)) {
my ($tag, $wiretype, $bytes_read) = read_tag($handle);
$total_bytes_read += $bytes_read;
if ($tag == 1 && $wiretype == WIRE_TYPE_VARINT) {
($obj->[0], $bytes_read) = read_varint($handle);
}
# add more cases here, one for each field
$total_bytes_read += $bytes_read;
}
return $obj;
}
sub parse_message_from_delimited_handle
{
my $handle = shift;
my ($num_bytes, $bytes_read) = read_varint($handle);
return parse_message_from_handle($handle, $num_bytes);
}
my $count;
for (1..10_000_000) {
$count++;
parse_message_from_handle($handle);
}
print "$count\n";
=pack templates for non varint types
quads might have to be emulated using BigInt, depending on the system architecture
this will be hell of slow but it'll make them work. read 4 bytes, shift 32 bits to
the left, read 4 more bytes, add to the result of the first.
fixed32 => '<L'
sfixed32 => '<l'
fixed64 => '<Q'
sfixed64 => '<q'
double => '<d'
float => '<f'
everything else is either a varint or a length-delimited field.
to encode sin32 and sint64, first pass the value through shifts to produce a zig-zagged version,
then write as a varint.
each value n is encoded using
(n << 1) ^ (n >> 31)
for sint32s, or
(n << 1) ^ (n >> 63)
for sint64s
=cut