File Coverage

blib/lib/App/colourhexdump/Formatter.pm
Criterion Covered Total %
statement 26 83 31.3
branch 0 10 0.0
condition n/a
subroutine 9 19 47.3
pod 6 6 100.0
total 41 118 34.7


line stmt bran cond sub pod time code
1 2     2   551 use 5.006; # our
  2         6  
2 2     2   10 use strict;
  2         3  
  2         48  
3 2     2   9 use warnings;
  2         3  
  2         163  
4              
5             package App::colourhexdump::Formatter;
6              
7             our $VERSION = '1.000003';
8              
9             # ABSTRACT: Colour-Highlight lines of data as hex.
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13 2     2   505 use Moose qw( has );
  2         296791  
  2         18  
14 2     2   9437 use String::RewritePrefix;
  2         1623  
  2         7  
15 2     2   311 use Module::Runtime qw( require_module );
  2         4  
  2         13  
16 2     2   725 use Term::ANSIColor 3.00 qw( colorstrip );
  2         4548  
  2         1164  
17              
18 2     2   412 use namespace::autoclean;
  2         7540  
  2         12  
19              
20             has colour_profile => (
21             does => 'App::colourhexdump::ColourProfile',
22             is => 'rw',
23             lazy_build => 1,
24             init_arg => undef,
25             );
26              
27             has real_colour_profile_class => (
28             isa => 'Str',
29             is => 'rw',
30             lazy_build => 1,
31             init_arg => undef,
32             );
33              
34             has colour_profile_class => (
35             isa => 'Str',
36             is => 'rw',
37             init_arg => 'colour_profile',
38             default => 'DefaultColourProfile',
39             );
40              
41             has row_length => (
42             isa => 'Int',
43             is => 'ro',
44             default => 32,
45             );
46              
47             has chunk_length => (
48             isa => 'Int',
49             is => 'rw',
50             default => 4,
51             );
52              
53             has hex_row_length => (
54             isa => 'Int',
55             is => 'rw',
56             lazy_build => 1,
57             init_arg => undef,
58             );
59              
60             __PACKAGE__->meta->make_immutable;
61 2     2   318 no Moose;
  2         4  
  2         14  
62              
63             sub _build_hex_row_length {
64 0     0     my $self = shift;
65              
66             # Each byte takes 2 bytes to print.
67             #
68 0 0         if ( $self->chunk_length > $self->row_length ) {
69 0           $self->chunk_length( $self->row_length );
70             }
71 0           my $real_chunk_length = $self->chunk_length * 2;
72              
73 0           my $chunks = int( $self->row_length / $self->chunk_length );
74 0           my $extrachunk = 0;
75              
76 0 0         if ( ( $chunks * $self->chunk_length ) < $self->row_length ) {
77 0           $extrachunk = $self->row_length - ( $chunks * $self->chunk_length );
78             }
79              
80 0           my $whitespaces = $chunks - 1;
81 0 0         if ( $extrachunk > 0 ) {
82 0           $whitespaces++;
83             }
84              
85 0           return ( $chunks * $real_chunk_length ) + $whitespaces + $extrachunk;
86              
87             }
88              
89              
90              
91              
92              
93              
94              
95              
96              
97              
98             ## no critic ( Subroutines::RequireArgUnpacking )
99              
100             sub format_foreach_in_fh {
101 0     0 1   my ( $self, $fh, $callback ) = ( $_[0], $_[1], $_[2] );
102 0           my $offset = 0;
103 0           while ( read $fh, my $buffer, $self->row_length ) {
104 0           $callback->( $self->format_row( $buffer, $offset ) );
105 0           $offset += $self->row_length;
106             }
107 0           return 1;
108             }
109              
110              
111              
112              
113              
114              
115              
116             ## no critic ( Subroutines::RequireArgUnpacking )
117              
118             sub format_row_from_fh {
119 0     0 1   my ( $self, $fh, $offset ) = ( $_[0], $_[1], $_[2] );
120 0 0         read $fh, my $buffer, $self->row_length or return;
121 0           my $str = $self->format_row( $buffer, $offset );
122 0           $offset += $self->row_length;
123 0           return $str, $offset;
124             }
125              
126              
127              
128              
129              
130              
131              
132             sub format_row {
133 0     0 1   my ( $self, $row, $offset ) = @_;
134              
135 0           my $format = "%10s: %s %s\n";
136 0           my $offset_hex = _to_hex( pack q{N*}, $offset );
137              
138 0           my @chars = split //, $row;
139              
140 0           return sprintf $format, $offset_hex, $self->pad_hex_row( $self->hex_encode(@chars) ), $self->pretty_encode(@chars);
141             }
142              
143              
144              
145              
146              
147              
148              
149             sub hex_encode {
150 0     0 1   my ( $self, @chars ) = @_;
151 0           my @out;
152 0           while ( my @vals = splice @chars, 0, $self->chunk_length, () ) {
153 0           my $chunk;
154 0           for (@vals) {
155 0           $chunk .= $self->colour_profile->get_string_pre($_);
156 0           $chunk .= _to_hex($_);
157 0           $chunk .= $self->colour_profile->get_string_post($_);
158             }
159 0           push @out, $chunk;
160             }
161 0           return join q{ }, @out;
162             }
163              
164              
165              
166              
167              
168              
169              
170             sub pretty_encode {
171 0     0 1   my ( $self, @chars ) = @_;
172 0           my $output;
173 0           for (@chars) {
174 0           $output .= $self->colour_profile->get_string_pre($_);
175 0           $output .= $self->colour_profile->get_display_symbol_for($_);
176 0           $output .= $self->colour_profile->get_string_post($_);
177             }
178 0           return $output;
179             }
180              
181             sub _to_hex {
182 0     0     return join q{}, map { unpack q{H*}, $_ } @_;
  0            
183             }
184              
185              
186              
187              
188              
189              
190              
191             sub pad_hex_row {
192 0     0 1   my ( $self, $row ) = @_;
193 0           my $length = length colorstrip($row);
194 0 0         if ( $length > $self->hex_row_length ) {
195 0           return $row;
196             }
197 0           return $row . ( q{ } x ( $self->hex_row_length - $length ) );
198             }
199              
200             sub _build_colour_profile {
201 0     0     my $self = shift;
202 0           require_module( $self->real_colour_profile_class );
203 0           return $self->real_colour_profile_class->new();
204             }
205              
206             sub _build_real_colour_profile_class {
207 0     0     my $self = shift;
208 0           return String::RewritePrefix->rewrite( { q{} => 'App::colourhexdump::', q{=} => q{} }, $self->colour_profile_class );
209             }
210              
211             1;
212              
213             __END__
214              
215             =pod
216              
217             =encoding UTF-8
218              
219             =head1 NAME
220              
221             App::colourhexdump::Formatter - Colour-Highlight lines of data as hex.
222              
223             =head1 VERSION
224              
225             version 1.000003
226              
227             =head1 METHODS
228              
229             =head2 format_foreach_in_fh
230              
231             $formatter->format_foreach_in_fh( $fh, sub {
232             my $formatted = shift;
233             print $formatted;
234             });
235              
236             =head2 format_row_from_fh
237              
238             my ( $formatted , $offset ) = $formatter->format_row_from_fh( $fh, $offset );
239              
240             =head2 format_row
241              
242             my $formatted = $formatter->format_row( "Some Characters", $offset );
243              
244             =head2 hex_encode
245              
246             my $hexes = $formatter->hex_encode( split //, "Some Characters" );
247              
248             =head2 pretty_encode
249              
250             my $nicetext = $formatter->pretty_encode( split //, "Some Characters" );
251              
252             =head2 pad_hex_row
253              
254             my $padded = $Formatter->pad_hex_row( $formatter->hex_enode( split //, "Some Characters" ) );
255              
256             =head1 AUTHOR
257              
258             Kent Fredric <kentnl@cpan.org>
259              
260             =head1 COPYRIGHT AND LICENSE
261              
262             This software is copyright (c) 2017 by Kent Fredric <kentnl@cpan.org>.
263              
264             This is free software; you can redistribute it and/or modify it under
265             the same terms as the Perl 5 programming language system itself.
266              
267             =cut