Badger::Codec::Chain - encode/decode data using multiple codecs


Badger documentation Contained in the Badger distribution.

Index


Code Index:

NAME

Top

Badger::Codec::Chain - encode/decode data using multiple codecs

SYNOPSIS

Top

    use Badger::Codec::Chain;

    # compact form
    my $codec = Badger::Codec::Chain->new('storable+base64');

    # explicit form
    my $codec = Badger::Codec::Chain->new('storable', 'base64');

    # encode/decode data using codec chain
    my $enc   = $codec->encode({ pi => 3.14, e => 2.718 });
    my $dec   = $codec->decode($encoded);

DESCRIPTION

Top

This module implements a subclass of Badger::Codec which chains together any number of other codec modules.

METHODS

Top

new(@codecs)

Constructor method to create a new codec chain. The codecs can be specified by name or as references to Badger::Codec objects.

    # by name
    my $codec = Badger::Codec::Chain->new('storable', 'base64');

    # by object reference
    my $codec = Badger::Codec::Chain->new(
        Badger::Codec->codec('storable'), 
        Badger::Codec->codec('base64'), 
    );

You can also use the compact form where multiple codec names are separated by +.

    # compact form
    my $codec = Badger::Codec::Chain->new('storable+base64');

encode($data)

Encodes the data referenced by the first argument using all the codecs in the chain.

    $encoded = $codec->encode($data);   

decode($html)

Decodes the encoded data passed as the first argument using all the codecs in the chain in reverse order.

    $decoded = $codec->decode($encoded);

encoder()

Returns a reference to a subroutine which performs the encoding operation.

decoder()

Returns a reference to a subroutine which performs the decoding operation.

INTERNAL METHODS

Top

coder(@coders)

Internal method to construct an encoder or decoder subroutine for a codec chain.

AUTHOR

Top

Andy Wardley http://wardley.org/

COPYRIGHT

Top

SEE ALSO

Top

Badger::Codecs, Badger::Codec.


Badger documentation Contained in the Badger distribution.

#========================================================================
#
# Badger::Codec::Storable
#
# DESCRIPTION
#   Codec for encoding/decoding data via a chain of other codecs.
#
# AUTHOR
#   Andy Wardley   <abw@wardley.org>
#
#========================================================================

package Badger::Codec::Chain;

use Badger::Codecs;
use Badger::Class
    version   => 0.01,
    debug     => 0,
    base      => 'Badger::Codec',
    constants => 'ARRAY',
    constant  => {
        CODECS  => 'Badger::Codecs',
        CHAIN   => __PACKAGE__,
        CHAINED => qr/\s*\+\s*/,
    },
    exports   => {
        any   => 'CHAIN CHAINED'
    };


sub new {
    my $class = shift;
    my $chain = @_ == 1 ? shift : [ @_ ];

    # single argument can be a text string or array ref
    # each argument in an array can be a codec ref or codec name/chain
    # all codec names must be upgraded to codec objects
    $chain = [ $chain ] unless ref $chain eq ARRAY;
    $chain = [ map { ref $_ ? $_ : split(CHAINED, $_) } @$chain ];
    $chain = [ map { ref $_ ? $_ : CODECS->codec($_)  } @$chain ];
    
    $class->debug("chaining codecs: ", join(' + ', @$chain), "\n") if $DEBUG;

    bless {
        chain => $chain,
    }, $class;
}

sub encode {
    my $self = shift;
    my $data = shift;
    foreach my $codec (@{ $self->{ chain } }) {
        $data = $codec->encode($data);
    }
    return $data;
}

sub decode {
    my $self = shift;
    my $data = shift;
    foreach my $codec (reverse @{ $self->{ chain } }) {
        $data = $codec->decode($data);
    }
    return $data;
}

sub encoder {
    my $self = shift;
    return $self->coder(
        map { $_->encoder } 
        @{ $self->{ chain } } 
    );
}

sub decoder {
    my $self = shift;
    return $self->coder(
        reverse map { $_->decoder } 
        @{ $self->{ chain } } 
    );
}

sub coder {
    my $self   = shift;
    my $coders = @_ && ref $_[0] eq ARRAY ? shift : [@_];
    return sub {
        my $data = shift;
        foreach my $coder (@$coders) {
            $data = $coder->($data);
        }
        return $data;
    }
}

1;

__END__

# Local Variables:
# mode: Perl
# perl-indent-level: 4
# indent-tabs-mode: nil
# End:
#
# vim: expandtab shiftwidth=4: