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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package bSerialize;
use strict;
use warnings;
use bytes;
use IO::String;
sub new{ return bless{
valcache => {}
}, shift }
sub val2bin{
my $self = shift;
my $val = shift;
return pack('NC',0,0) if ! defined $val;
my %cache = %{$self->{valcache}};
return $cache{$val} ? $cache{$val} : do{
my $bs = pack('NC', length($val), 1).$val;
$cache{$val} = $bs;
$bs;
};
}
sub array2bin{
my $self = shift;
my $aref = shift;
my $bs = '';
foreach my $e(@$aref){ $bs .= $self->val2bin($e) }
return $bs;
}
sub bin2array{
my $self = shift;
my $bs = shift;
my $io = IO::String->new;
$io->print($$bs);
$io->seek(0,0);
my @ret = ();
while( read($io, my $buffer, 5) ){
my ($len, $type) = unpack('NC', $buffer);
read($io, my $elem, $len);
if( $type == 0){ push @ret, undef }
else { push @ret, $elem }
}
return \@ret;
}
sub av2bin{
my $self = shift;
my $av = shift;
my $bs = '';
foreach my $att( keys %$av ){ $bs .= $self->val2bin($att).$self->val2bin($av->{$att}) }
return $bs;
}
sub bin2av{
my $self = shift;
my $bs = shift;
my %ret = @{$self->bin2array($bs)};
return \%ret;
}
sub eav2bin{
my $self = shift;
my $eav = shift;
my $bs = '';
foreach my $ent(keys %$eav){
foreach my $att(keys %{$eav->{$ent}}){
$bs .= $self->val2bin($ent).$self->val2bin($att).$self->val2bin( $eav->{$ent}{$att} );
}
}
return $bs;
}
sub bin2eav(){
my $self = shift;
my $bs = shift;
my $raw = $self->bin2array($bs);
my $eav = {};
while( my $ent = shift @$raw){
my $att = shift @$raw;
my $val = shift @$raw;
$eav->{$ent}{$att} = $val;
}
return $eav;
}
1;
use Data::Dumper;
my $bs = bSerialize->new();
my $bin = $bs->av2bin({
addr => $bs->av2bin( { name => 'foo', vname => 'bar', city => 'NY', nix => '', garnix => undef } ),
nums => $bs->array2bin( [undef, 0, 1, 2, 3, 9] ),
eav => $bs->eav2bin({ env => \%ENV, sig => \%SIG })
});
print Dumper $bin,
$bs->bin2av( \$bs->bin2av(\$bin)->{addr} ),
$bs->bin2array( \$bs->bin2av(\$bin)->{nums} ),
$bs->bin2eav( \$bs->bin2av(\$bin)->{eav} );