Data-Plist
view release on metacpan or search on metacpan
lib/Data/Plist/Writer.pm view on Meta::CPAN
=head1 NAME
Data::Plist::Writer - Object serializer and abstact
superclass for BinaryWriter and XMLWriter
=head1 SYNOPSIS
# Create new
my $write = Data::Plist::BinaryWriter->new;
# Writing to a string ($ret is binary output)
my $ret = $write->write($data);
# Writing to a file C<$filename>
$ret = $write->write($filename, $data);
=head1 DESCRIPTION
C<Data::Plist::Writer> is the abstract superclass of
L<Data::Plist::BinaryWriter> and L<Data::Plist::XMLWriter>. It takes
perl data structures, serializes them (see L<Data::Plist/SERIALIZED
DATA>), and recursively writes to a given filehandle in the desired
format.
=cut
package Data::Plist::Writer;
use strict;
use warnings;
use Storable;
use Digest::MD5;
use Scalar::Util;
=head1 METHODS
=cut
=head2 new
Creates a new writer. 'serialize' is set to 1 since it's
assumed that data being passed in will be perl data
structures that need to be serialized. Users may set it to
0 when creating a writer if they wish to use preserialized
data.
=cut
sub new {
my $class = shift;
my %args = ( serialize => 1, @_ );
return bless \%args => $class;
}
=head2 write $filehandle, $data
=head2 write $filename, $data
=head2 write $data
Takes a perl data structure C<$data> and writes to the given
filehandle C<$filehandle>, or filename C<$filename>. If only the
C<$data> is provided, returns the data to be written, as a string.
=cut
sub write {
my $self = shift;
my $object = pop;
my $to = shift;
if ( not $to ) {
my $content = '';
my $fh;
open( $fh, ">", \$content );
$self->write_fh( $fh, $object ) or return;
return $content;
} elsif ( ref $to ) {
$self->write_fh( $to, $object );
} else {
my $fh;
open( $fh, ">", $to ) or die "Can't open $to for writing: $!";
$self->write_fh( $fh, $object ) or return;
}
return;
}
=head2 fold_uids $data
Takes a serialized object C<$data> (see
L<Data::Plist/SERIALIZED DATA>) and rewrites it as a keyed
archive (see L<Data::Plist/KEYED ARCHIVES>) by folding on
UIDs.
=cut
sub fold_uids {
my $self = shift;
my $data = shift;
if ( $data->[0] eq "UID" ) {
local $Storable::canonical = 1;
my $digest = Digest::MD5::md5_hex( Storable::freeze( $data->[1] ) );
if ( exists $self->{objcache}{$digest} ) {
return [ UID => $self->{objcache}{$digest} ];
}
push @{ $self->{objects} }, $self->fold_uids( $data->[1] );
$self->{objcache}{$digest} = @{ $self->{objects} } - 1;
return [ UID => @{ $self->{objects} } - 1 ];
} elsif ( $data->[0] eq "array" ) {
return [ "array", [ map { $self->fold_uids($_) } @{ $data->[1] } ] ];
} elsif ( $data->[0] eq "dict" ) {
( run in 0.599 second using v1.01-cache-2.11-cpan-99c4e6809bf )