File Coverage

blib/lib/MooX/Pack/Base.pm
Criterion Covered Total %
statement 53 53 100.0
branch 8 8 100.0
condition 6 6 100.0
subroutine 6 6 100.0
pod 0 3 0.0
total 73 76 96.0


line stmt bran cond sub pod time code
1             package MooX::Pack::Base;
2              
3 3     3   35851 use Moo::Role;
  3         85  
  3         22  
4 3     3   1414 use Carp;
  3         23  
  3         2697  
5              
6             has [qw/raw_data data/] => (
7             is => 'rw',
8             lazy => 1,
9             );
10              
11             has [qw/line_spec all_spec/] => (
12             is => 'ro',
13             builder => 1,
14             );
15              
16             has [qw/pack_templates/] => (
17             is => 'rw',
18             builder => 1,
19             lazy => 1
20             );
21              
22             sub _build_pack_templates {
23 2     2   28 my ($all, $line, @templates) = ($_[0]->all_spec, $_[0]->line_spec);
24 2         3 my %ordered_line = map { $line->{$_}->{index} => $line->{$_}->{spec} } keys %{ $line };
  4         19  
  2         8  
25 2         12 for ( 0 .. ( scalar (keys %ordered_line) - 1 )) {
26 4         10 push @templates, $ordered_line{$_};
27             }
28 2         5 for my $line ( @templates ) {
29 4         6 my $push = scalar @{ $line };
  4         7  
30 4         14 for (my $i = $push - 1; $i > 0; $i--) {
31 8         10 splice @{ $line }, $i, 0, { %{ $all } };
  8         12  
  8         32  
32             }
33             }
34 2         10 return \@templates;
35             }
36              
37             sub build_pack_string {
38 5     5 0 10 my ($spec, $string, @keys) = ($_[1], '');
39 5         8 for (@{ $spec }) {
  5         10  
40 25         42 $string = sprintf('%s%s', $string, $_->{character});
41 25   100     64 my $key = ($_->{key} || $_->{name});
42 25 100       49 push @keys, $key if $key;
43             }
44 5         17 return ($string, @keys);
45             }
46              
47             sub unpack {
48 2     2 0 55 my ($template, $line, @unpacking) = ($_[0]->pack_templates, 0);
49 2         22 for($_[0]->raw_data =~ /([^\n]+)\n?/g){
50 5         14 my ($pack_string, @keys) = $_[0]->build_pack_string($template->[$line]);
51 5         24 my @unpack = unpack($pack_string, $_);
52 5         5 my %hashed;
53 5         35 @hashed{@keys} = @unpack;
54 5         9 push @unpacking, \%hashed;
55 5 100       7 $line++ if scalar @{$template} - 1 > $line;
  5         35  
56             }
57 2         9 $_[0]->data(\@unpacking);
58 2         6 return \@unpacking;
59             }
60              
61             sub pack {
62 2     2 0 3006 my ($template, $line, @packing) = ($_[0]->pack_templates, 0);
63 2         19 for my $data (@{ $_[0]->data }) {
  2         12  
64 5         6 my $pack;
65 5         8 for (@{$template->[$line]}) {
  5         12  
66 25   100     87 my $key = ($_->{key} || $_->{name});
67 25         56 (my $sep = $_->{character}) =~ s/(x)/a/g;
68 25 100       73 $pack .= pack($sep, $key ? $data->{$key} : $_->{pack});
69             }
70 5         9 push @packing, $pack;
71 5 100       7 $line++ if scalar @{$template} - 1 > $line;
  5         17  
72             }
73 2         6 my $packed = join "\n", @packing;
74 2         23 $_[0]->raw_data($packed);
75 2         8 return $packed;
76             }
77              
78             1;