File Coverage

blib/lib/Data/StreamDeserializer.pm
Criterion Covered Total %
statement 84 95 88.4
branch 33 46 71.7
condition 3 8 37.5
subroutine 17 18 94.4
pod 11 11 100.0
total 148 178 83.1


line stmt bran cond sub pod time code
1             package Data::StreamDeserializer;
2              
3 7     7   336664 use 5.010001;
  7         30  
  7         296  
4 7     7   43 use strict;
  7         10  
  7         262  
5 7     7   33 use warnings;
  7         15  
  7         316  
6 7     7   38 use Carp;
  7         13  
  7         867  
7              
8             require Exporter;
9 7     7   6441 use AutoLoader;
  7         11167  
  7         43  
10              
11             our @ISA = qw(Exporter);
12             our $VERSION = '0.06';
13              
14 7     7   536 use XSLoader;
  7         13  
  7         7449  
15             XSLoader::load('Data::StreamDeserializer', $VERSION);
16              
17             sub new
18             {
19 52     52 1 1748206 my ($class, %opts) = @_;
20 52   33     388 my $class_name = ref($class) || $class;
21              
22 52         1598 my $self = $class_name->_low_level_new;
23 52 100       239 $self->block_size($opts{block_size}) if exists $opts{block_size};
24 52 100       496 if (exists $opts{data}) {
25 51         246 $self->part($opts{data});
26 51         157 $self->part;
27             }
28 52         239 return $self;
29             }
30              
31              
32             sub block_size
33             {
34 15739     15739 1 128423 my ($self, $value) = @_;
35 15739 100       33570 return $self->{block_size} unless @_ > 1;
36 15738 50       28021 croak "You can't set zero block_size" unless $value;
37 15738         37714 return $self->{block_size} = $value;
38             }
39              
40              
41             sub part
42             {
43 15837     15837 1 29725 my ($self, @data) = @_;
44 15837 100       34075 goto SET_EOF unless @data;
45 15786 100       36615 goto SET_EOF unless defined $data[0];
46 15785         50548 $self->{data} .= join '', @data;
47 15785         26619 return;
48              
49 52 50       228 SET_EOF:
50             $self->{data} .= ' ' unless $self->{eof}; # hack for tail digists
51 52         101 $self->{eof} = 1;
52 52         139 return;
53             }
54              
55              
56             sub next
57             {
58 29610     29610 1 116548 my ($self, @data) = @_;
59              
60 29610 100       81598 $self->part(@data) if @data;
61              
62              
63 29610 100       68244 return 1 if $self->{done};
64 29609 100       92506 if ($self->{seen} < -1 + length $self->{data}) {
65 29608 100       1244908 return 0 unless $self->_ds_look_tail;
66 14871         61570 goto CHECK_ERROR;
67             }
68 1 50       11 goto CHECK_ERROR if $self->{eof};
69 0         0 return 0;
70              
71 14872         25044 CHECK_ERROR:
72             my $mode = $self->{mode};
73 14872 100       30273 if ($mode < 0) {
74 3         20 $self->_push_error($self->_error_string);
75 3         6 delete $self->{data};
76 3         10 return $self->{done} = 1;
77             }
78 14869 100       33645 if ($self->{eof}) {
79 49 50       198 return 0 if $self->{seen} < -1 + length $self->{data};
80 49 50       86 if (@{$self->{markers}}) {
  49         178  
81 0         0 $self->_push_error(
82             sprintf "Unclosed brackets: '%s'",
83 0         0 join "', '", map $_->[0], @{ $self->{markers} }
84             );
85             }
86 49         712 delete $self->{data};
87 49         230 return $self->{done} = 1;
88             }
89              
90 14820         64815 return 0;
91             }
92              
93             sub is_done
94             {
95 18     18 1 42 my ($self) = @_;
96 18         37 return $self->{done};
97             }
98              
99             sub next_object
100             {
101 65     65 1 232 my ($self, @data) = @_;
102 65         79 my $cnt = $self->{object_counter};
103              
104 65         71 $self->{one_object_mode} = 1;
105 65         96 my $res = $self->next(@data);
106 65         81 $self->{one_object_mode} = 0;
107 65 100       166 return 1 if $res;
108 62         141 return $cnt < $self->{object_counter};
109             }
110              
111             sub skip_divider
112             {
113 6     6 1 20 my ($self) = @_;
114 6         22 $self->_skip_divider;
115             }
116              
117             sub is_error
118             {
119 21     21 1 54 my ($self) = @_;
120 21         42 return scalar @{ $self->{error} };
  21         79  
121             }
122              
123             sub error
124             {
125 0     0 1 0 my ($self) = @_;
126 0 0       0 return '' unless @{ $self->{error} };
  0         0  
127 0         0 return join "\n", @{ $self->{error} };
  0         0  
128             }
129              
130              
131             sub tail
132             {
133 15     15 1 20 my ($self) = @_;
134 15 50       33 if ($self->{eof}) {
135 15 50       31 return '' unless length $self->{tail};
136 15         71 return substr $self->{tail}, 0, -1 + length $self->{tail};
137             }
138 0         0 return $self->{tail};
139             }
140              
141              
142             sub result
143             {
144 18     18 1 55 my ($self, $behaviour) = @_;
145 18   50     82 $behaviour ||= 'first';
146 18 50       101 return $self->{queue}[0] if $behaviour eq 'first';
147 0 0       0 return $self->{queue} if $behaviour eq 'all';
148 0         0 croak "Unknown behaviour '$behaviour'";
149             }
150              
151             sub _push_error
152             {
153 3     3   6 my ($self, $error) = @_;
154 3 50 33     3 return if @{$self->{error}} and $self->{error}[-1] eq $error;
  3         13  
155 3         6 push @{ $self->{error} }, $error;
  3         8  
156 3         6 return;
157             }
158              
159             1;
160              
161             __END__