App-jl
view release on metacpan or search on metacpan
lib/App/jl.pm view on Meta::CPAN
while ($self->{__current_orig_line} = <STDIN>) {
if (my $line = $self->_run_line) {
print $out $line;
}
$self->{__current_orig_line} = undef;
}
}
sub _run_line {
my ($self) = @_;
if ($self->{__current_orig_line} =~ m!^[\s\t\r\n]+$!) {
return;
}
if ($self->{__current_orig_line} !~ m!^\s*[\[\{]!) {
return $self->opt('sweep') ? undef : $self->{__current_orig_line};
}
if (my $rs = $self->opt('grep')) {
if (!$self->_match_grep($rs)) {
return; # no match
}
}
if (my $rs = $self->opt('ignore')) {
if ($self->_match_grep($rs)) {
return; # ignore if even one match
}
}
return $self->_process;
}
sub _match_grep {
my ($self, $rs) = @_;
for my $r (@{$rs}) {
return 1 if $self->{__current_orig_line} =~ m!$r!;
}
}
sub _lazyload_modules {
my ($self) = @_;
if ($self->opt('xxxx') || $self->opt('timestamp_key')) {
require 'POSIX.pm'; ## no critic
POSIX->import;
}
if ($self->opt('yaml')) {
require 'YAML/Syck.pm'; ## no critic
YAML::Syck->import;
$YAML::Syck::SortKeys = 1;
}
}
sub _process {
my ($self) = @_;
my $decoded = eval {
$self->{_json}->decode($self->{__current_orig_line});
};
if ($@) {
return $self->{__current_orig_line};
}
else {
$self->_recursive_process($decoded);
return $self->_encode($decoded);
}
}
sub _encode {
my ($self, $decoded) = @_;
if ($self->opt('yaml')) {
return YAML::Syck::Dump($decoded);
}
else {
return $self->{_json}->encode($decoded);
}
}
sub _recursive_process {
my ($self, $decoded) = @_;
$self->_recursive_pre_process($decoded);
$self->{_recursive_call} = $MAX_RECURSIVE_CALL;
$self->_recursive_decode_json($decoded);
$self->_recursive_post_process($decoded);
}
sub _recursive_pre_process {
my ($self, $decoded) = @_;
$INVOKER->invoke(\&_trim => $decoded);
$self->_invoker(\&_split_lf => $decoded) if $self->opt('x');
}
sub _recursive_post_process {
my ($self, $decoded) = @_;
if ($self->opt('x')) {
$self->_invoker(\&_split_lf => $decoded);
}
if ($self->opt('xx')) {
$self->_invoker(\&_split_comma => $decoded);
}
if ($self->opt('xxx')) {
$self->_invoker(\&_split_label => $decoded);
}
if ($self->opt('xxxx') || $self->opt('timestamp_key')) {
if ($self->opt('xxxxx')) {
$INVOKER->invoke(\&_forcely_convert_timestamp => $decoded);
}
else {
$self->_invoker(\&_convert_timestamp => $decoded);
}
}
$INVOKER->invoke(\&_trim => $decoded);
}
my $LAST_VALUE;
sub _invoker {
my ($self, $code_ref, $hash) = @_;
$LAST_VALUE = '';
$INVOKER->massive_invoke($code_ref => $hash);
}
sub _skippable_value {
my ($context, $last_value) = @_;
return $context && $context eq 'HASH'
&& $last_value && $last_value =~ m!user[\-\_\s]*agent!i;
}
sub _split_lf {
my $line = $_[0];
my $context = $_[1];
if (_skippable_value($context, $LAST_VALUE)) {
$LAST_VALUE = $line;
return $line;
}
$LAST_VALUE = $line;
if ($line =~ m![\t\r\n]!) {
chomp $line;
my @elements = split /[\t\r\n]+/, $line;
$_[0] = \@elements if scalar @elements > 1;
}
}
sub _split_comma {
my $line = $_[0];
my $context = $_[1];
if (_skippable_value($context, $LAST_VALUE)) {
$LAST_VALUE = $line;
return $line;
}
$LAST_VALUE = $line;
return $line if $line !~ m!, ! || $line =~ m!\\!;
chomp $line;
my @elements = split /,\s+/, $line;
$_[0] = \@elements if scalar @elements > 1;
}
sub _split_label {
my $line = $_[0];
my $context = $_[1];
lib/App/jl.pm view on Meta::CPAN
}
}
$LAST_VALUE = $line;
}
sub _forcely_convert_timestamp {
my $line = $_[0];
if ($line =~ m!(\d+(\.\d+)?)!) {
if (my $date = _ts2date($1, $2)) {
$_[0] = $date;
}
}
}
sub _ts2date {
my $unix_timestamp = shift;
my $msec = shift || '';
# 946684800 = 2000-01-01T00:00:00Z
if ($unix_timestamp >= 946684800 && $unix_timestamp <= ((2**32 - 1) * 1000)) {
if ($unix_timestamp > 2**32 -1) {
($msec) = ($unix_timestamp =~ m!(\d\d\d)$!);
$msec = ".$msec";
$unix_timestamp = int($unix_timestamp / 1000);
}
my @t = $GMTIME ? gmtime($unix_timestamp) : localtime($unix_timestamp);
return POSIX::strftime('%Y-%m-%d %H:%M:%S', @t) . $msec;
}
}
sub _trim {
my $line = $_[0];
my $trim = 0;
if ($line =~ m!^[\s\t\r\n]+!) {
$line =~ s!^[\s\t\r\n]+!!;
$trim = 1;
}
if ($line =~ m![\s\t\r\n]+$!) {
$line =~ s![\s\t\r\n]+$!!;
$trim = 1;
}
if ($trim) {
$_[0] = $line;
}
}
sub _recursive_decode_json {
my ($self, $hash) = @_;
Sub::Data::Recursive->invoke(sub {
if ($self->{_recursive_call} > 0) {
my $orig = $_[0];
return if $orig =~ m!^\[\d+\]$!;
if (!_is_number($_[0])) {
my $decoded = eval {
$self->{_json}->decode($orig);
};
if (!$@) {
$_[0] = $decoded;
$self->{_recursive_call}--;
$self->_recursive_decode_json($_[0]); # recursive calling
}
}
}
} => $hash);
}
# copied from Data::Recursive::Encode
sub _is_number {
my $value = shift;
return 0 unless defined $value;
my $b_obj = B::svref_2object(\$value);
my $flags = $b_obj->FLAGS;
return $flags & ( B::SVp_IOK | B::SVp_NOK ) && !( $flags & B::SVp_POK ) ? 1 : 0;
}
sub _parse_opt {
my ($class, @argv) = @_;
my $opt = {};
GetOptionsFromArray(
\@argv,
'no-pretty' => \$opt->{no_pretty},
'x' => \$opt->{x},
'xx' => \$opt->{xx},
'xxx' => \$opt->{xxx},
'xxxx' => \$opt->{xxxx},
'X|xxxxx' => \$opt->{xxxxx},
'timestamp-key=s' => \$opt->{timestamp_key},
'gmtime' => \$opt->{gmtime},
'g|grep=s@' => \$opt->{grep},
'ignore=s@' => \$opt->{ignore},
'yaml|yml' => \$opt->{yaml},
'unbuffered' => \$opt->{unbuffered},
'stderr' => \$opt->{stderr},
'sweep' => \$opt->{sweep},
'h|help' => sub {
$class->_show_usage(1);
},
'v|version' => sub {
print "$0 $VERSION\n";
exit 1;
},
) or $class->_show_usage(2);
$opt->{xxxx} ||= $opt->{xxxxx};
$opt->{xxx} ||= $opt->{xxxx};
$opt->{xx} ||= $opt->{xxx};
$opt->{x} ||= $opt->{xx};
$UNIXTIMESTAMP_KEY = $opt->{timestamp_key};
$GMTIME = $opt->{gmtime};
return $opt;
}
( run in 0.531 second using v1.01-cache-2.11-cpan-9581c071862 )