#
# $Id: Serializer.pm,v 0.1 2001/04/22 17:57:03 ram Exp $
#
# Copyright (c) 1998-2001, Raphael Manfredi
# Copyright (c) 2000-2001, Christophe Dehaudt
#
# You may redistribute only under the terms of the Artistic License,
# as specified in the README file that comes with the distribution.
#
# HISTORY
# $Log: Serializer.pm,v $
# Revision 0.1 2001/04/22 17:57:03 ram
# Baseline for first Alpha release.
#
# $EndLog$
#
use strict;
package CGI::MxScreen::Serializer;
use Carp::Datum;
use Log::Agent;
#
# ->make
#
# Creation routine.
#
sub make { logconfess "deferred" }
#
# ->_init
#
# Records freezer, thawer and compression parameters.
#
sub _init {
DFEATURE my $f_;
my $self = shift;
my ($freeze, $thaw, $compress) = @_;
$self->{freezer} = $freeze;
$self->{thawer} = $thaw;
$self->{compress} = $compress;
}
#
# Attributes
#
sub freezer { $_[0]->{freezer} }
sub thawer { $_[0]->{thawer} }
sub compress { $_[0]->{compress} }
#
# ->serialize
#
# Serialize reference.
# Returns frozen string, undef on error.
#
sub serialize {
DFEATURE my $f_;
my $self = shift;
my ($ref) = @_;
DREQUIRE ref $ref, "serializing a reference";
my $frozen;
eval {
$frozen = &{$self->freezer}($ref);
};
logerr "unable to serialize $ref: $@" if chop $@;
return DVAL undef unless defined $frozen;
if ($self->compress) {
require Compress::Zlib;
$frozen = Compress::Zlib::compress($frozen);
}
return DVAL $frozen;
}
#
# ->deserialize
#
# Deserialize frozen string, passed as reference.
# Returns ref to thawed data.
#
sub deserialize {
my $self = shift;
my ($frozen) = @_;
DREQUIRE !ref $frozen, "deserializing a scalar";
if ($self->compress) {
require Compress::Zlib;
$frozen = Compress::Zlib::uncompress($frozen);
}
my $data;
eval {
$data = &{$self->thawer}($frozen);
};
logerr "unable to deserialize $frozen: $@" if chop $@;
return DVAL undef unless defined $data;
DENSURE ref $data, "data returned as reference";
return DVAL $data;
}
1;
=head1 NAME
CGI::MxScreen::Serializer - Abstract serializer interface
=head1 SYNOPSIS
# Deferred class, only heirs may be instantiated
# In heirs:
use base qw(CGI::MxScreen::Serializer);
sub make { # define the creation routine
...
$self->_init(\&freeze, \&thaw, $compress);
}
# Access interface - $ser is an instantiated heir
my $serialized = $ser->serialize($ref);
my $deserialized = $ser->deserialize($serialized);
=head1 DESCRIPTION
This module implements a serializer abstraction and should probably be
a CPAN module of its own. I'm seriously thinking about it.
The C<CGI::MxScreen::Serializer> class is B<deferred>. The only thing
it lacks is a creation routine, which will initialize the
C<freeze> and C<thaw> attributes with code references to the proper
freezing and thawing routines.
It bluntly assumes those routine will conform to the following signatures:
freeze(x: REF): STRING
thaw(x: STRING): REF
and satisfy the following condition, for every I<x>:
thaw(freeze(x)).deep_equal(x)
where I<deep_equal> is an operation testing that its arguments are
structurally equivalent, whatever that means.
This class also supports on-the-fly compression and decompression of the
serialized data via C<Compress::Zlib>.
=head1 SUPPORTED SERIALIZERS
Currently, the only serializer available is
C<CGI::MxScreen::Serializer::Storable> which is simply installing
C<Storable>.
=head1 INTERFACE
=head2 Attributes
The following read-only attributes are defined. The are meant to be
initialized at creation time via C<_init()>:
=over 4
=item C<compress>
A boolean flag, stating whether C<Compress::Zlib> compression and decompression
should be performed.
=item C<freezer>
A CODE reference on the freezing routine.
=item C<thawer>
A CODE reference on the thawing routine.
=back
=head2 Routines
=over 4
=item C<_init> I<freezer>, I<thawer>, I<compress_flag>
This routine must be called by the C<make()> routine in heirs to initialize
the attributes.
=item C<deserialize> I<frozen>
Deserialize the I<frozen> serialized string generated by C<serialize()>
and return a reference to its root object.
=item C<serialize> I<reference>
Serialize the I<reference> and return a string that can be deserialized
by C<deserialize>.
=back
=head1 AUTHOR
Raphael Manfredi F<E<lt>Raphael_Manfredi@pobox.comE<gt>>
=head1 SEE ALSO
CGI::MxScreen::Serializer::Storable(3).
=cut