File Coverage

blib/lib/Data/Buffer.pm
Criterion Covered Total %
statement 107 108 99.0
branch 25 36 69.4
condition 2 2 100.0
subroutine 28 28 100.0
pod 23 26 88.4
total 185 200 92.5


line stmt bran cond sub pod time code
1             # $Id: Buffer.pm,v 1.9 2001/07/28 06:36:50 btrott Exp $
2              
3             package Data::Buffer;
4 1     1   15383 use strict;
  1         3  
  1         80  
5              
6 1     1   8 use vars qw( $VERSION );
  1         3  
  1         1651  
7             $VERSION = '0.04';
8              
9             sub new {
10 5     5 1 134 my $class = shift;
11 5         10 my %arg = @_;
12 5         30 bless { buf => "", offset => 0, template => "" }, $class;
13             }
14              
15             sub new_with_init {
16 2     2 1 5 my $class = shift;
17 2         5 my $buf = $class->new;
18 2         561 $buf->append($_) for @_;
19 2         8 $buf;
20             }
21              
22             sub extract {
23 1     1 1 2 my $buf = shift;
24 1         2 my($nbytes) = @_;
25 1         4 my $new = ref($buf)->new;
26 1         4 $new->append( $buf->get_bytes($nbytes) );
27 1         3 $new;
28             }
29              
30             sub empty {
31 2     2 1 546 my $buf = shift;
32 2         5 $buf->{buf} = "";
33 2         4 $buf->{offset} = 0;
34 2         5 $buf->{template} = "";
35             }
36              
37 2     2 1 7 sub set_offset { $_[0]->{offset} = $_[1] }
38 1     1 1 6 sub reset_offset { $_[0]->set_offset(0) }
39              
40             sub insert_template {
41 1     1 0 3 my $buf = shift;
42 1         6 $buf->bytes(0, 0, $buf->{template} . chr(0));
43             }
44              
45             sub append {
46 6     6 1 9 my $buf = shift;
47 6         17 $buf->{buf} .= $_[0];
48             }
49              
50             sub bytes {
51 41     41 1 53 my $buf = shift;
52 41         54 my($off, $len, $rep) = @_;
53 41   100     92 $off ||= 0;
54 41 100       78 $len = length $buf->{buf} unless defined $len;
55 41 100       200 return defined $rep ?
56             substr($buf->{buf}, $off, $len, $rep) :
57             substr($buf->{buf}, $off, $len);
58             }
59              
60 9     9 1 114 sub length { length $_[0]->{buf} }
61 7     7 1 30 sub offset { $_[0]->{offset} }
62 1     1 0 5 sub template { $_[0]->{template} }
63              
64             sub dump {
65 3     3 1 7 my $buf = shift;
66 3         4 my @r;
67 3         9 for my $c (split //, $buf->bytes(@_)) {
68 3         15 push @r, sprintf "%02x", ord $c;
69 3 50       11 push @r, "\n" unless @r % 24;
70             }
71 3         14 join ' ', @r
72             }
73              
74             sub get_all {
75 1     1 0 2 my $buf = shift;
76 1 50       13 my($tmpl, $data) = $buf->{buf} =~ /^([NYaCn\d]+)\0(.+)$/s or
77             die "Buffer $buf does not appear to contain a template";
78 1         3 my $b = __PACKAGE__->new;
79 1         3 $b->append($data);
80 1         9 my @tmpl = split //, $tmpl;
81 1         2 my @data;
82 1         5 while (@tmpl) {
83 10         20 my $el = shift @tmpl;
84 10 100       36 if ($el eq "N") {
    100          
    100          
    100          
    50          
85 3 100       16 next if $tmpl[0] eq "Y"; ## Peek ahead: is it a string?
86 1         8 push @data, $b->get_int32;
87             }
88             elsif ($el eq "n") {
89 1         3 push @data, $b->get_int16;
90             }
91             elsif ($el eq "C") {
92 1         3 push @data, $b->get_int8;
93             }
94             elsif ($el eq "a") {
95 3         4 my $len = shift @tmpl;
96 3         14 push @data, $b->get_char for 1..$len;
97             }
98             elsif ($el eq "Y") {
99 2         5 push @data, $b->get_str;
100             }
101             else {
102 0         0 die "Unrecognized template token: $el";
103             }
104             }
105 1         19 @data;
106             }
107              
108             sub get_int8 {
109 2     2 1 4 my $buf = shift;
110 2 50       6 my $off = defined $_[0] ? shift : $buf->{offset};
111 2         5 $buf->{offset} += 1;
112 2         3 unpack "C", $buf->bytes($off, 1);
113             }
114              
115             sub put_int8 {
116 1     1 1 2 my $buf = shift;
117 1         4 $buf->{buf} .= pack "C", $_[0];
118 1         3 $buf->{template} .= "C";
119             }
120              
121             sub get_int16 {
122 4     4 1 8 my $buf = shift;
123 4 50       25 my $off = defined $_[0] ? shift : $buf->{offset};
124 4         7 $buf->{offset} += 2;
125 4         9 unpack "n", $buf->bytes($off, 2);
126             }
127              
128             sub put_int16 {
129 2     2 1 6 my $buf = shift;
130 2         7 $buf->{buf} .= pack "n", $_[0];
131 2         4 $buf->{template} .= "n";
132             }
133              
134             sub get_int32 {
135 6     6 1 8 my $buf = shift;
136 6 50       15 my $off = defined $_[0] ? shift : $buf->{offset};
137 6         8 $buf->{offset} += 4;
138 6         13 unpack "N", $buf->bytes($off, 4);
139             }
140              
141             sub put_int32 {
142 3     3 1 5 my $buf = shift;
143 3         10 $buf->{buf} .= pack "N", $_[0];
144 3         7 $buf->{template} .= "N";
145             }
146              
147             sub get_char {
148 13     13 1 16 my $buf = shift;
149 13 50       29 my $off = defined $_[0] ? shift : $buf->{offset};
150 13         16 $buf->{offset}++;
151 13         22 $buf->bytes($off, 1);
152             }
153              
154             sub put_char {
155 2     2 1 4 my $buf = shift;
156 2         5 $buf->{buf} .= $_[0];
157 2         7 $buf->{template} .= "a" . CORE::length($_[0]);
158             }
159              
160             sub get_bytes {
161 4     4 1 7 my $buf = shift;
162 4         6 my($nbytes) = @_;
163 4         11 my $d = $buf->bytes($buf->{offset}, $nbytes);
164 4         10 $buf->{offset} += $nbytes;
165 4         15 $d;
166             }
167              
168             sub put_bytes {
169 1     1 1 2 my $buf = shift;
170 1         3 my($str, $nbytes) = @_;
171 1 50       6 $buf->{buf} .= $nbytes ? substr($str, 0, $nbytes) : $str;
172 1 50       5 $buf->{template} .= "a" . ($nbytes ? $nbytes : CORE::length($str));
173             }
174              
175             *put_chars = \&put_char;
176              
177             sub get_str {
178 4     4 1 6 my $buf = shift;
179 4 50       16 my $off = defined $_[0] ? shift : $buf->{offset};
180 4         11 my $len = $buf->get_int32;
181 4         10 $buf->{offset} += $len;
182 4         9 $buf->bytes($off+4, $len);
183             }
184              
185             sub put_str {
186 2     2 1 41 my $buf = shift;
187 2         4 my $str = shift;
188 2 50       8 $str = "" unless defined $str;
189 2         8 $buf->put_int32(CORE::length($str));
190 2         3 $buf->{buf} .= $str;
191 2         4 $buf->{template} .= "Y";
192             }
193              
194             1;
195             __END__