#!/usr/bin/perl
##LICENSE##
# Perl implementation of PHP's native serialize() and unserialize() functions.
#
# Scott Hurring
# scott at hurring dot com
# http://hurring.com/
# Please be nice and send bugfixes and code improvements to http://hurring.com/code/perl/serialize/.
#
# @version v0.91
# @author Scott Hurring; scott at hurring dot com
# @copyright Copyright (c) 2005 Scott Hurring
# @license http://opensource.org/licenses/gpl-license.php GNU Public License
#
# Most recent version can be found at:
# http://hurring.com/code/perl/serialize/
#
# =====================================================================
package RVSInstaller::Serialize;
use strict;
use Carp;
use Exporter;
use vars qw($VERSION @ISA @EXPORT $SERIALIZE_DBG);
@ISA = qw(Exporter);
@EXPORT = qw(serialize unserialize);
$VERSION = 0.91;
our $SERIALIZE_DBG = 0;
sub serialize {
my ($ref) = @_;
my $s;
if ( ref($ref) =~ /hash|array/i ) {
$s = serialize_sub( $ref, '', 1 );
}
else {
return serialize_value($ref);
}
return $s;
}
sub serialize_sub {
my ( $ref, $k, $no_key ) = @_;
my $s;
$s .= serialize_value($k) unless ($no_key);
if ($no_key) {
#print "\n\nno_key is set, ref=$ref, ". ref($ref) .", k=$k, s=$s\n\n";
}
if ( ref($ref) =~ /hash/i ) {
my $num = keys( %{$ref} );
$s .= "a:$num:{";
foreach my $k ( keys(%$ref) ) {
$s .= serialize_sub( $$ref{$k}, $k );
}
$s .= "}";
}
elsif ( ref($ref) =~ /array/i ) {
my $num = @{$ref};
$s .= "a:$num:{";
for ( my $k = 0 ; $k < @$ref ; $k++ ) {
$s .= serialize_sub( $$ref[$k], $k );
}
$s .= "}";
}
elsif ( !ref($ref) ) {
$s .= serialize_value($ref);
}
else {
die( "Cannot handle $ref = type (" . ref($ref) . ")" );
}
return $s;
}
sub serialize_value {
my ($value) = @_;
my $s;
if ( $value =~ /^\-?\d+$/ ) {
if ( abs($value) > 2**32 ) {
$s = "d:$value;";
}
else {
$s = "i:$value;";
}
}
elsif ( $value =~ /^\-?(\d+)\.(\d+)$/ ) {
$s = "d:$value;";
}
elsif ( $value eq "\0" ) {
$s = "N;";
}
else {
my $vlen = length($value);
$s = "s:$vlen:\"$value\";";
}
return $s;
}
sub unserialize {
my ($string) = @_;
if ( $string =~/^a:(\d+):(\{(.*)\})$/s ) {
print "Unserializing complex array ($string)" if ($SERIALIZE_DBG);
my $keys = $1 * 2;
my @chars = split( //, $2 );
undef $string;
return unserialize_sub( {}, $keys, \@chars );
}
elsif ( $string =~/^s/ ) {
print "Unserializing single string ($string)" if ($SERIALIZE_DBG);
$string =~/^s:(\d+):/;
return substr( $string, length($1) + 4, $1 );
}
elsif ( $string =~/^i|^d/ ) {
print "Unserializing integer or double ($string)" if ($SERIALIZE_DBG);
return substr( $string, 2 ) + 0;
}
elsif ( $string =~/^N/i ) {
print "Unserializing NULL value ($string)" if ($SERIALIZE_DBG);
return "\0";
}
else {
print "Unserializing BAD DATA! ($string)" if ($SERIALIZE_DBG);
return '';
}
}
sub unserialize_sub {
my ( $hashref, $keys, $chars ) = @_;
my ( $temp, $keyname, $skip, $strlen );
my $mode = 'normal';
print "unserialize: $hashref, $keys, $chars\n" if ($SERIALIZE_DBG);
while ( defined( my $c = shift @{$chars} ) ) {
print "\t[$mode] = $c\n" if ($SERIALIZE_DBG);
if ( $mode eq 'string' ) {
$skip = 1;
if ( $c =~/\d+/ ) {
$strlen = $strlen . $c;
print "string length = $strlen ($c)\n" if ($SERIALIZE_DBG);
}
if ( ( $strlen =~/\d+/ ) && ( $c eq ':' ) ) {
$mode = 'readstring';
}
}
elsif ( $mode eq 'readstring' ) {
next if ( $skip-- > 0 );
$mode = 'set', next if ( !$strlen-- );
$temp .= $c;
}
elsif ( $mode eq 'integer' ) {
next if ( $c eq ':' );
$mode = 'set', next if ( $c eq ';' );
if ( $c =~/\-|\d+/ ) {
if ( $c eq '-' ) {
$temp .= $c unless $temp;
}
else {
$temp .= $c;
}
}
}
elsif ( $mode eq 'double' ) {
next if ( $c eq ':' );
$mode = 'set', next if ( $c eq ';' );
if ( $c =~/\-|\d+|\./ ) {
if ( $c eq '-' ) {
$temp .= $c unless $temp;
}
else {
$temp .= $c;
}
}
}
elsif ( $mode eq 'null' ) {
$temp = "\0";
$mode = 'set', next;
}
elsif ( $mode eq 'array' ) {
if ( $c eq '{' ) {
$$hashref{$keyname} = unserialize_sub( $$hashref{$keyname}, ( $temp * 2 ), $chars );
undef $keyname;
$mode = 'normal';
}
elsif ( $c =~/\d+/ ) {
$temp = $temp . $c;
print "array_length = $temp ($c)\n" if ($SERIALIZE_DBG);
}
}
elsif ( $mode eq 'set' ) {
if ( defined($keyname) ) {
print "set VALUE=$temp\n" if ($SERIALIZE_DBG);
$$hashref{$keyname} = $temp;
undef $keyname;
}
else {
print "set KEYNAME=$temp\n" if ($SERIALIZE_DBG);
$keyname = $temp;
}
$mode = 'normal';
}
if ( $mode eq 'normal' ) {
$strlen = $temp = '';
if ( !$keys ) {
print "return, no more keys to process = ($keys)\n"
if ($SERIALIZE_DBG);
return $hashref;
}
if ( $c eq 'i' ) {
$mode = 'integer';
$keys--;
}
if ( $c eq 'd' ) {
$mode = 'double';
$keys--;
}
if ( $c eq 'b' ) {
$mode = 'integer';
$keys--;
}
if ( $c eq 's' ) {
$mode = 'string';
$keys--;
}
if ( $c eq 'a' ) {
$mode = 'array';
$keys--;
}
if ( $c eq 'N' ) {
$mode = 'null';
$keys--;
}
}
}
print "return normally (chars=" . ( join ',', @$chars ) . ")\n" if ($SERIALIZE_DBG);
return $hashref;
}
1;
__END__
Copyright 2K16 - 2K18 Indonesian Hacker Rulez