File Coverage

blib/lib/Data/Transform/Reference.pm
Criterion Covered Total %
statement 48 49 97.9
branch 16 18 88.8
condition 2 3 66.6
subroutine 11 11 100.0
pod 3 3 100.0
total 80 84 95.2


line stmt bran cond sub pod time code
1             # vim: ts=2 sw=2 expandtab
2             package Data::Transform::Reference;
3 1     1   1604 use strict;
  1         3  
  1         50  
4 1     1   667 use Data::Transform;
  1         3  
  1         30  
5              
6 1     1   6 use vars qw($VERSION @ISA);
  1         1  
  1         68  
7             $VERSION = '0.01';
8             @ISA = qw(Data::Transform);
9              
10 1     1   5 use Carp qw(croak);
  1         1  
  1         528  
11              
12             sub INPUT () { 0 }
13             sub BUFFER () { 1 }
14             sub SERIALIZE () { 2 }
15             sub DESERIALIZE () { 3 }
16              
17             =pod
18              
19             =head1 NAME
20              
21             Data::Transform::Reference - freeze and thaw arbitrary Perl data
22              
23             =head1 SYNOPSIS
24              
25             use YAML;
26             use Data::Transform::Reference;
27              
28             my $filter = Data::Transform::Reference->new(
29             serialize => YAML->can('Dump');
30             deserialize => YAML->can('Load');
31             );
32              
33             ...
34             my $string = $filter->put($some_var);
35              
36             ...
37             my $other_var = $filter->get($serialized_var);
38              
39             =head1 DESCRIPTION
40              
41             Data::Transform::Reference allows programs to send and receive arbitrary
42             Perl data structures without worrying about a line protocol. Its
43             put() method serializes Perl data into a byte stream suitable for
44             transmission. get_one() parses the data structures back out of such a
45             stream.
46              
47             =head1 METHODS
48              
49             Data::Transform::Reference implements the standard Data::Transform API. Only
50             the differences are documented here.
51              
52             =cut
53              
54             =head2 new
55              
56             new() creates and initializes a Data::Transform::Reference object. It
57             requires the following parameters:
58              
59             =over 2
60              
61             =item serializer
62              
63             A code ref used to serialize data. Good candidates for this are nfreeze()
64             from L or Dump() from a YAML implementation.
65              
66             =item deserializer
67              
68             A code ref used to de-serialize data. Good candidates for this are thaw()
69             from L or Load() from a YAML implementation.
70              
71             =back
72              
73             Both code references are expected to accept a single parameter containing
74             the data on which to act on.
75              
76             =cut
77              
78             sub new {
79 6     6 1 21556 my $type = shift;
80              
81 6 50       23 croak "$type requires an even number of arguments"
82             if (@_ & 1);
83              
84 6         19 my %param = @_;
85              
86 6 100       246 croak "$type requires a serialize parameter"
87             unless defined $param{'serialize'};
88 5 100       170 croak "$type: serialize parameter must be a CODE reference"
89             unless (ref $param{'serialize'} eq 'CODE');
90 4 100       173 croak "$type requires a deserialize parameter"
91             unless defined $param{'deserialize'};
92 3 100       144 croak "$type: deserialize parameter must be a CODE reference"
93             unless (ref $param{'deserialize'} eq 'CODE');
94            
95              
96 2         31 my $self = bless [
97             [], # INPUT
98             '', # BUFFER
99             $param{'serialize'}, # FREEZE
100             $param{'deserialize'}, # THAW
101             ];
102              
103 2         12 return bless $self, $type;
104             }
105              
106             sub clone {
107 1     1 1 1230 my $self = shift;
108              
109 1         5 my $new = [
110             [],
111             '',
112             $self->[SERIALIZE],
113             $self->[DESERIALIZE],
114             ];
115              
116 1         7 return bless $new, ref $self;
117             }
118              
119             sub get_pending {
120 4     4 1 17 my $self = shift;
121 4         6 my @ret;
122              
123 4         21 @ret = @{$self->[INPUT]};
  4         13  
124 4 50       19 if (length $self->[BUFFER]) {
125 0         0 unshift @ret, $self->[BUFFER];
126             }
127              
128 4 100       25 return @ret ? \@ret : undef;
129             }
130              
131             sub _handle_get_data {
132 18     18   27 my ($self, $data) = @_;
133              
134 18 100       37 if (defined $data) {
135 6         13 $self->[BUFFER] .= $data;
136             }
137              
138             # Need to check lengths in octets, not characters.
139 1     1   7 use bytes;
  1         2  
  1         7  
140              
141 18 100 66     84 if ($self->[BUFFER] =~ /^(\d+)\0/ and
142             length($self->[BUFFER]) >= $1 + length($1) + 1 ) {
143              
144 6         20 substr($self->[BUFFER], 0, length($1) + 1) = "";
145 6         15 my $return = substr($self->[BUFFER], 0, $1);
146 6         14 substr($self->[BUFFER], 0, $1) = "";
147 6         17 return $self->[DESERIALIZE]->($return);
148             }
149              
150 12         39 return;
151             }
152              
153             sub _handle_put_data {
154 4     4   6 my ($self, $reference) = @_;
155              
156             # Need to check lengths in octets, not characters.
157 1     1   216 use bytes;
  1         2  
  1         4  
158              
159 4         15 my $frozen = $self->[SERIALIZE]->($reference);
160 4         155 return length($frozen) . "\0" . $frozen;
161             }
162              
163             1;
164              
165             __END__