File Coverage

blib/lib/Data/BitStream/BLVec.pm
Criterion Covered Total %
statement 15 17 88.2
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Data::BitStream::BLVec;
2 27     27   27174 use strict;
  27         70  
  27         1291  
3 27     27   168 use warnings;
  27         51  
  27         1446  
4             BEGIN {
5 27     27   647 $Data::BitStream::BLVec::AUTHORITY = 'cpan:DANAJ';
6             }
7             BEGIN {
8 27     27   507 $Data::BitStream::BLVec::VERSION = '0.08';
9             }
10              
11 27     27   183 use Moo;
  27         55  
  27         196  
12 27     27   27924 use MooX::Types::MooseLike::Base qw/InstanceOf/;
  27         78703  
  27         3361  
13              
14             with 'Data::BitStream::Base',
15             'Data::BitStream::Code::Gamma',
16             'Data::BitStream::Code::Delta',
17             'Data::BitStream::Code::Omega',
18             'Data::BitStream::Code::Levenstein',
19             'Data::BitStream::Code::EvenRodeh',
20             'Data::BitStream::Code::Fibonacci',
21             'Data::BitStream::Code::Golomb',
22             'Data::BitStream::Code::Rice',
23             'Data::BitStream::Code::GammaGolomb',
24             'Data::BitStream::Code::ExponentialGolomb',
25             'Data::BitStream::Code::Baer',
26             'Data::BitStream::Code::BoldiVigna',
27             'Data::BitStream::Code::ARice',
28             'Data::BitStream::Code::Additive',
29             'Data::BitStream::Code::Comma',
30             'Data::BitStream::Code::Taboo',
31             'Data::BitStream::Code::BER',
32             'Data::BitStream::Code::Varint',
33             'Data::BitStream::Code::StartStop';
34              
35 27     27   13834 use Data::BitStream::XS 0.04;
  0            
  0            
36              
37             has '_vec' => (is => 'rw',
38             isa => InstanceOf['Data::BitStream::XS'],
39             default => sub { return Data::BitStream::XS->new });
40              
41             # Force our pos and len sets to also set the XS object
42             has '+pos' => (trigger => sub { shift->_vec->_set_pos(shift) });
43             has '+len' => (trigger => sub { shift->_vec->_set_len(shift) });
44              
45             after 'rewind' => sub { shift->_vec->rewind; 1; };
46             after 'erase' => sub { shift->_vec->erase; 1; };
47             after 'read_open' => sub { shift->_vec->read_open; 1; };
48             after 'write_open' => sub { shift->_vec->write_open; 1; };
49             after 'write_close' => sub { shift->_vec->write_close; 1; };
50              
51             sub read {
52             my $self = shift;
53             my $vref = $self->_vec;
54              
55             my $val = $vref->read(@_);
56             $self->_setpos( $vref->pos );
57             $val;
58             }
59             sub write {
60             my $self = shift;
61             my $vref = $self->_vec;
62              
63             $vref->write(@_);
64              
65             $self->_setlen( $vref->len );
66             1;
67             }
68              
69             # This is a bit ugly, but my other alternatives:
70             #
71             # 1) hand-write each sub.
72             # Error prone, and lots of duplication.
73             #
74             # 2) make a _generic_put and then:
75             # sub put_unary { _generic_put( sub { shift->put_unary(shift) }, @_) }
76             # Very nice, but adds time for every value
77             #
78             # 3) _generic_put with a for loop inside the sub argument.
79             # Solves performance, but now unwieldy and not generic.
80             #
81             # 3) Use *{$fn} = sub { ... }; instead of eval.
82             # 100ns slower, which is 0.5-2x the total function cost
83             #
84              
85             sub _generate_generic_put {
86             my $param = shift;
87             my $fn = shift;
88             my $blfn = shift || $fn;
89              
90             my $st = "sub $fn {\n " .
91             ' my $self = shift;
92             __PARAM__
93             my $vref = $self->_vec;
94             $vref->__CALLFUNC__;
95             $self->_setlen( $vref->len );
96             1;
97             }';
98              
99             $st =~ s/__PARAM__/$param/;
100             $st =~ s/__CALLFUNC__/$blfn(\@_)/g;
101              
102             { no warnings 'redefine'; eval $st; } ## no critic
103             warn $@ if $@;
104             }
105             sub _generate_generic_get {
106             my $param = shift;
107             my $fn = shift;
108             my $blfn = shift || $fn;
109              
110             my $st = "sub $fn {\n " .
111             ' my $self = shift;
112             __PARAM__
113             my $vref = $self->_vec;
114             if (wantarray) {
115             my @vals = $vref->__CALLFUNC__;
116             $self->_setpos( $vref->pos );
117             return @vals;
118             } else {
119             my $val = $vref->__CALLFUNC__;
120             $self->_setpos( $vref->pos );
121             return $val;
122             }
123             }';
124              
125             $st =~ s/__PARAM__/$param/;
126             $st =~ s/__CALLFUNC__/$blfn(\@_)/g;
127              
128             { no warnings 'redefine'; eval $st; } ## no critic
129             warn $@ if $@;
130             }
131              
132             sub _generate_generic_getput {
133             my $param = shift;
134             my $code = shift;
135             my $blcode = shift || $code;
136             _generate_generic_put($param, 'put_'.$code, 'put_'.$blcode );
137             _generate_generic_get($param, 'get_'.$code, 'get_'.$blcode );
138             }
139              
140             _generate_generic_getput('', 'unary');
141             _generate_generic_getput('', 'unary1');
142             _generate_generic_getput('', 'gamma');
143             _generate_generic_getput('', 'delta');
144             _generate_generic_getput('', 'omega');
145             _generate_generic_getput('', 'fib');
146             _generate_generic_getput('', 'fibgen');
147             _generate_generic_getput('', 'levenstein');
148             _generate_generic_getput('', 'evenrodeh');
149             _generate_generic_getput('', 'gammagolomb');
150             _generate_generic_getput('', 'expgolomb');
151             _generate_generic_getput('', 'baer');
152             _generate_generic_getput('', 'boldivigna');
153             _generate_generic_getput('', 'comma');
154             _generate_generic_getput('', 'blocktaboo');
155             _generate_generic_getput('', 'goldbach_g1');
156             _generate_generic_getput('', 'goldbach_g2');
157             _generate_generic_getput('', 'binword');
158              
159             # The XS module understands subs, so we can map these directly
160             _generate_generic_getput('', 'golomb');
161             _generate_generic_getput('', 'rice');
162             _generate_generic_getput('', 'arice');
163              
164             _generate_generic_getput('', 'startstepstop');
165             _generate_generic_getput('', 'startstop');
166              
167             #_generate_generic_get('', 'get_levenstein');
168             #_generate_generic_get(
169             # 'die "invalid parameters" unless $p > 0 && $p <= 15',
170             # 'get_boldivigna');
171             #_generate_generic_getput(
172             # 'die "invalid parameters" unless $p >= 0 && $p <= $self->maxbits',
173             # 'expgolomb', 'gamma_rice');
174              
175             sub put_string {
176             my $self = shift;
177             my $vref = $self->_vec;
178              
179             $vref->put_string(@_);
180              
181             $self->_setlen( $vref->len );
182             1;
183             }
184              
185             sub read_string { shift->_vec->read_string(@_); }
186              
187             sub to_raw {
188             my $self = shift;
189             $self->write_close;
190             my $vref = $self->_vec;
191             return $vref->to_raw;
192             }
193             sub put_raw {
194             my $self = shift;
195             my $vref = $self->_vec;
196             $vref->put_raw(@_);
197             $self->_setlen( $vref->len );
198             1;
199             }
200             sub from_raw {
201             my $self = $_[0];
202             # data comes in 2nd argument
203             my $bits = $_[2] || 8*length($_[1]);
204              
205             $self->write_open;
206             my $vref = $self->_vec;
207             $vref->from_raw($_[1], $bits);
208              
209             $self->_setlen( $bits );
210             $self->rewind_for_read;
211             }
212              
213             sub put_stream {
214             my $self = shift;
215             my $source = shift;
216             my $vref = $self->_vec;
217              
218             if (ref $source eq __PACKAGE__) {
219             $vref->put_stream($source->_vec);
220             } else {
221             $vref->put_stream($source);
222             }
223              
224             $self->_setlen( $vref->len );
225             1;
226             }
227              
228             # default everything else
229              
230             __PACKAGE__->meta->make_immutable;
231             no Moo;
232             1;
233              
234             # ABSTRACT: An XS-wrapper implementation of Data::BitStream
235              
236             =pod
237              
238             =head1 NAME
239              
240             Data::BitStream::BLVec - An XS-wrapper implementation of Data::BitStream
241              
242             =head1 SYNOPSIS
243              
244             use Data::BitStream::BLVec;
245             my $stream = Data::BitStream::BLVec->new;
246             $stream->put_gamma($_) for (1 .. 20);
247             $stream->rewind_for_read;
248             my @values = $stream->get_gamma(-1);
249              
250              
251              
252             =head1 DESCRIPTION
253              
254             An implementation of L. See the documentation for that
255             module for many more examples, and L for the API.
256             This document only describes the unique features of this implementation,
257             which is of limited value to people purely using L.
258              
259             This implementation points everything to the implementations in
260             Data::BitStream::XS where possible. This gives the majority of the performance
261             benefit of the XS module, while (1) transparently applying the speedup through
262             the Data::BitStream package, and (2) allowing all the Moo/Mouse/Moose extensions
263             and extra roles to be used while still retaining high performance at the core.
264              
265             This is the default L implementation if Data::BitStream::XS
266             is installed.
267              
268              
269              
270             =head2 DATA
271              
272             =over 4
273              
274             =item B< _vec >
275              
276             A private Data::BitStream::XS object.
277              
278             =back
279              
280              
281              
282             =head2 CLASS METHODS
283              
284             =over 4
285              
286             =item I B< erase >
287              
288             =item I B< rewind >
289              
290             =item I B< read_open >
291              
292             =item I B< write_open >
293              
294             =item I B< write_close >
295              
296             Applies the appropriate behavior to the XS object.
297              
298              
299             =item B< read >
300              
301             =item B< write >
302              
303             =item B< put_string >
304              
305             =item B< read_string >
306              
307             =item B< to_raw >
308              
309             =item B< put_raw >
310              
311             =item B< from_raw >
312              
313             =item B< put_stream >
314              
315             These methods have custom implementations.
316              
317             The following codes have C and C methods:
318              
319             unary
320             unary1
321             gamma
322             delta
323             omega
324             fib
325             fibgen
326             levenstein
327             evenrodeh
328             gammagolomb
329             expgolomb
330             baer
331             boldivigna
332             comma
333             blocktaboo
334             goldbach_g1
335             goldbach_g2
336             binword
337             golomb
338             rice
339             arice
340             startstepstop
341             startstop
342              
343             =back
344              
345              
346             =head2 ROLES
347              
348             The following roles are included.
349              
350             =over 4
351              
352             =item L
353              
354             =item L
355              
356             =item L
357              
358             =item L
359              
360             =item L
361              
362             =item L
363              
364             =item L
365              
366             =item L
367              
368             =item L
369              
370             =item L
371              
372             =item L
373              
374             =item L
375              
376             =item L
377              
378             =item L
379              
380             =item L
381              
382             =item L
383              
384             =item L
385              
386             =item L
387              
388             =back
389              
390              
391              
392              
393             =head1 SEE ALSO
394              
395             =over 4
396              
397             =item L
398              
399             =item L
400              
401             =item L
402              
403             =item L
404              
405             =back
406              
407              
408              
409             =head1 AUTHORS
410              
411             Dana Jacobsen Edana@acm.orgE
412              
413              
414              
415             =head1 COPYRIGHT
416              
417             Copyright 2011-2012 by Dana Jacobsen Edana@acm.orgE
418              
419             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
420              
421             =cut