Storable::AMF0 - serializing/deserializing AMF0 data


Storable-AMF documentation Contained in the Storable-AMF distribution.

Index


Code Index:

NAME

Top

Storable::AMF0 - serializing/deserializing AMF0 data

SYNOPSIS

Top

  use Storable::AMF0 qw(freeze thaw); # or use Storable::AMF3 qw(freeze thaw) for AMF3 format

  $amf0 = freeze($perl_object);
  $perl_object = thaw($amf0);

	


  # Store/retrieve to disk amf0 data

  store $perl_object, 'file';
  $restored_perl_object = retrieve 'file';




  use Storable::AMF0 qw(nstore freeze thaw dclone);

  # Network order: Due to spec of AMF0 format objects (hash, arrayref) stored in network order.
  # and thus nstore and store are synonyms 

  nstore \%table, 'file';
  $hashref = retrieve('file'); 

  


  # Advisory locking
  use Storable::AMF0 qw(lock_store lock_nstore lock_retrieve)
  lock_store \%table, 'file';
  lock_nstore \%table, 'file';
  $hashref = lock_retrieve('file');

  # Deparse one object
  use Storable::AMF0 qw(deparse_amf); 

  my( $obj, $length_of_packet ) = deparse_amf( my $bytea = freeze($a1) . freeze($a) ... );

  - or -
  $obj = deparse_amf( freeze($a1) . freeze($a) ... );

  # JSON::XS boolean support

  use JSON::XS;

  $json =  encode_json( thaw( $amf0, parse_serializator_option( 'json_boolean' ))); #  

  $amf_with_boolean = freeze( $JSON::XS::true  or $JSON::XS::false);

  # boolean support;

  use boolean;
  $amf_with_boolean = freeze( boolean( 1 or '' ));

  # Options support 
  use Storable::AMF[03] qw(parse_option parse_serializator_option);

  my $options = parse_serializator_option( "raise_error, prefer_number, json_boolean" ); # or parse
  $obj = thaw( $amf, $options );
  $amf = freeze( $obj, $options );

DESCRIPTION

Top

This module is (de)serializer for Adobe's AMF0/AMF3 (Action Message Format ver 0-3). This is only module and it recognize only AMF0 data. Almost all function implemented in C for speed. And some cases faster then Storable( for me always)

EXPORT

Top

  None by default.

FUNCTIONS =cut

Top

freeze($obj [, $option ]) --- Serialize perl object($obj) to AMF0, and return AMF0 data
thaw($amf0, [, $option ]) --- Deserialize AMF0 data to perl object, and return the perl object
store $obj, $file --- Store serialized AMF0 data to file
nstore $obj, $file --- Same as store
retrieve $obj, $file --- Retrieve serialized AMF0 data from file
lock_store $obj, $file --- Same as store but with Advisory locking
lock_nstore $obj, $file --- Same as lock_store
lock_retrieve $file --- Same as retrieve but with advisory locking
dclone $file --- Deep cloning data structure
ref_clear $obj --- recurrent refs clearing . (Succefully destroy recurrent objects with circular links too)
ref_lost_memory $obj --- test if object contain lost memory fragments inside. (Example do { my $a = []; @$a=$a; $a})
deparse_amf $bytea --- deparse from bytea one item Return one object and number of bytes readed if scalar context return object
parse_option( $option_string ) =item parse_serializator_option( $option_string ) --- generate option scalar from string usefull for some options of thaw/freeze/deparse_amf

OPTIONS There are several options supported

Top

strict
    --- strict mode ( DoS related option)

json_boolean
	--- support for JSON::XS boolean

prefer_number
	--- try freezing double val scalars as numbers

millisecond_date (depreciated don't use it)
raise_error
utf8_decode
utf8_encode

NOTICE

Top

  Storable::AMF0 is currently is at development stage. 

LIMITATION

Top

At current moment and with restriction of AMF0/AMF3 format referrences to scalar are not serialized, and can't/ may not serialize tied variables.

FEATURES

Top

	Due bug of Macromedia 'XML' type not serialized properly (it loose all atributes for AMF0) 
	For AMF0 has to use XMLDocument type.

SEE ALSO

Top

Data::AMF, Storable, Storable::AMF3

AUTHOR

Top

Anatoliy Grishaev, <grian at cpan dot org>

THANKS

Top

	Alberto Reggiori. ( basic externalized object support )
	Adam Lounds.      ( tests and some ideas and code for boolean support )




COPYRIGHT AND LICENSE

Top


Storable-AMF documentation Contained in the Storable-AMF distribution.
package Storable::AMF0;
use strict;
use warnings;
use Fcntl qw(:flock);
our $VERSION = '1.00';
use subs qw(freeze thaw);
use Scalar::Util qw(refaddr reftype);    # for ref_circled
use Exporter 'import';
use Carp qw(croak);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

our %EXPORT_TAGS = (
    'all' => [
        qw(
          freeze thaw	dclone
          retrieve lock_retrieve lock_store lock_nstore store nstore
          ref_lost_memory ref_clear
          deparse_amf new_amfdate perl_date
		  new_date
		  parse_option
		  parse_serializator_option
          )
    ]
);

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw();

sub retrieve($) {
    my $file = shift;
    my $lock = shift;

    open my $fh, "<:raw", $file or croak "Can't open file \"$file\" for read.";
    flock $fh, LOCK_SH if $lock;
    my $buf;
    sysread $fh, $buf, (( sysseek $fh, 0, 2 ), sysseek $fh, 0,0)[0] ;
    return thaw($buf);
}

sub lock_retrieve($) {
    $_[1] = 1;
    goto &retrieve;
}

sub store($$) {
    my ( $object, $file, $lock ) = @_;

    my $freeze = \freeze($object);
    unless (defined $$freeze ){
        croak "Bad object";
    }
    else  {
	open my $fh, ">:raw", $file or croak "Can't open file \"$file\" for write.";
        flock $fh, LOCK_EX if $lock;
        print $fh $$freeze if defined $$freeze;
    };
}

sub lock_store($$) {
    $_[2] = 1;
    goto &store;
}
sub ref_lost_memory($);
sub ref_clear($);
{{
	require XSLoader;
	XSLoader::load( 'Storable::AMF', $VERSION );
    no warnings 'once';
    *nstore = \&store;
    *lock_nstore = \&lock_store;

	no strict 'refs';

	my $my_package = __PACKAGE__ . "::";
	for my $other_package ( "Storable::AMF::", "Storable::AMF3::" ){
#	print STDERR "*{ $other_package$_ } = *{ $my_package$_}\n" for qw(ref_clear ref_lost_memory);
		*{ $other_package . $_ } = *{ $my_package . $_} for qw(ref_clear ref_lost_memory VERSION);
	}
	*{"Storable::AMF::$_"} = *{"Storable::AMF0::$_"} for grep m/retrieve|store/, @EXPORT_OK;
}};

sub _ref_selfref($$);

sub _ref_selfref($$) {
    my $obj_addr = shift;
    my $value    = shift;
    my $addr     = refaddr $value;
    return unless defined $addr;
    if ( reftype $value eq 'ARRAY' ) {

        return $$obj_addr{$addr} if exists $$obj_addr{$addr};
        $$obj_addr{$addr} = 1;
        _ref_selfref( $obj_addr, $_ ) && return 1 for @$value;
        $$obj_addr{$addr} = 0;
    }
    elsif ( reftype $value eq 'HASH' ) {

        return $$obj_addr{$addr} if exists $$obj_addr{$addr};
        $$obj_addr{$addr} = 1;
        _ref_selfref( $obj_addr, $_ ) && return 1 for values %$value;
        $$obj_addr{$addr} = 0;
    }
    else {
        return;
    }

    return;
}


sub ref_clear($) {
    my $ref = shift;
    my %addr;
    return unless ( refaddr $ref);
    my @r;
    if ( reftype $ref eq 'ARRAY' ) {
        @r    = @$ref;
        @$ref = ();
        ref_clear($_) for @r;
    }
    elsif ( reftype $ref eq 'HASH' ) {
        @r    = values %$ref;
        %$ref = ();
        ref_clear($_) for @r;
    }
}

sub ref_lost_memory($) {
    my $ref = shift;
    my %obj_addr;
    return _ref_selfref( \%obj_addr, $ref );
}

1;
__END__
# Below is stub documentation for your module. You'd better edit it!