File Coverage

blib/lib/BSON/Stream.pm
Criterion Covered Total %
statement 20 50 40.0
branch 1 14 7.1
condition n/a
subroutine 5 7 71.4
pod 0 3 0.0
total 26 74 35.1


line stmt bran cond sub pod time code
1             package BSON::Stream;
2              
3 1     1   16749 use strict;
  1         2  
  1         32  
4 1     1   4 use warnings;
  1         1  
  1         23  
5              
6 1     1   384 use BSON qw/decode/;
  1         19373  
  1         75  
7 1     1   11 use Carp;
  1         2  
  1         410  
8              
9             our $VERSION = '0.01';
10              
11             =head1 NAME
12              
13             BSON::Stream - Read BSON data from stream (file).
14              
15             =head1 SYNOPSIS
16             use BSON::Stream;
17            
18             my $file = shift @ARGV or die("Pleas specify a file to read!");
19            
20             open(my $INF,$file) or die("Can not open file '$file':$!");
21            
22             my $bsonstream = BSON::Stream->new($INF);
23            
24             while (my $res = $bsonstream->get) {
25            
26             printf("%s own %s apples\n",$res->{'name'}, $res->{'apples'});
27              
28             }
29            
30             close($INF);
31            
32             =head1 DESCRIPTION
33              
34             BSON::Stream allows you to read one and one BSON record from a file and get it back as a Perl structure.
35              
36             =head2 Reading from STDIN
37              
38             use BSON::Stream;
39            
40             my $bsonstream = BSON::Stream->new(*STDIN);
41            
42             while (my $res = $bsonstream->get) {
43            
44             printf("%s own %s apples\n",$res->{'name'}, $res->{'apples'});
45            
46             }
47              
48             BSON files can quickly become very large. One common way of dealing with this is to compress them using gzip, then use zcat to uncompressed and pipe the raw BSON data into a program on the fly.
49              
50             zcat eg/testdata/users.bson.gz | perl eg/synopsis-STDIN.pl
51              
52             =cut
53              
54              
55             sub new {
56 1     1 0 8 my $class = shift;
57              
58 1         2 my $self = {};
59 1         2 bless( $self, $class );
60            
61 1         4 $self->{'stream'} = shift;
62            
63             # Defaults to STDIN
64 1 50       3 if (!$self->{'stream'}) {
65 1         3 $self->{'stream'} = *STDIN;
66             }
67            
68             # We need to set the strem to be binery so Windows (and maby others) do not tranlate \n
69 1         3 binmode($self->{'stream'});
70            
71 1         3 return $self;
72             }
73              
74              
75             sub get {
76 0     0 0   my ($self) = @_;
77            
78 0           while (1) {
79 0           my $sizebits;
80             my $n;
81 0           my $bson;
82 0           my $res;
83            
84 0           $n = read($self->{'stream'}, $sizebits, 4);
85 0 0         if ($n != 4) {
86 0           $self->readerror($n);
87 0           return undef;
88             }
89            
90 0           my $size = unpack("i", $sizebits);
91              
92 0           $size -= 4;# -4 becase the size includes itself
93            
94            
95 0           $n = read($self->{'stream'}, $bson, $size);
96 0 0         if ($n != $size) {
97 0           $self->readerror($n);
98 0           return undef;
99             }
100            
101 0           $bson = $sizebits . $bson;
102            
103 0           my $seperator = substr($bson, -1,1);
104              
105 0 0         if ($seperator ne "\x00") {
106 0           carp("Bad record seperator '$seperator'");
107 0           return undef;
108             }
109              
110 0           eval {
111 0           $res = decode( $bson );
112             };
113             # If we can not decode we will just skipp. Having some bad records we
114             #can not decode are unfortantly not unkommon in large datasets.
115 0 0         if ($@) {
116 0           carp $@;
117 0           next;
118             }
119              
120            
121 0           return $res;
122            
123             }
124            
125             }
126              
127             sub readerror {
128 0     0 0   my ($self, $n) = @_;
129            
130 0 0         if ($n == 0) {
    0          
131             # End of file
132             }
133             elsif (!defined($n)) {
134 0           carp("Can not read from stream: $!");
135             }
136             else {
137 0           carp("Unknown error. Was not able to read all bytes.");
138             }
139             }
140              
141             =head1 EXAMPLES
142              
143             Please see the C directory for further examples.
144              
145             =head1 SEE ALSO
146              
147             F
148              
149             =head1 AUTHOR
150              
151             Runar Buvik
152             CPAN ID: RUNARB
153             runarb@gmail.com
154             http://www.runarb.com
155              
156             =head1 Git
157              
158             https://github.com/runarbu/PerlBSONStream
159              
160             =head1 COPYRIGHT
161              
162             This program is free software; you can redistribute
163             it and/or modify it under the same terms as Perl itself.
164              
165             The full text of the license can be found in the
166             LICENSE file included with this module.
167              
168              
169             =cut
170              
171             1;