#!/usr/bin/perl
# this softwary by Musicman 2003
# is covered by the GPL
# for the exact terms and conditions please see http://www.fsf.org/
#
package swfdata;
use constant PUSHDATA => "\x96";
use constant POP => "\x17";
use constant GETMEMBER => "\x4e";
use constant SETMEMBER => "\x4f";
use constant GETVAR => "\x1c";
use constant SETVAR => "\x1d";
use constant INITARRAY => "\x42";
use constant INITOBJECT => "\x43";
use constant CALLMETHOD => "\x52";
use constant CALLFUNCTION => "\x3d";
sub new
{ my $this = {};
bless $this;
$this->{hdr1} = "FWS\5";
$this->{hdr2} = "\110\1\220\0\144\0\0\14\1\0";
$this->{bgcol} = pack("v", (9 << 6) + 3) . "\377\377\377";
$this->{end} = pack("vv", 1 << 6, 0); # showframe, end
$this->{push_action} = '';
return $this;
}
sub send
{ my $this = shift;
$this->{actions} .= "\0";
my $len = length ($this->{actions});
if($len > 63)
{ $this->{actions} = pack("vV", (12 << 6) + 63, $len) . $this->{actions};
}
else
{ $this->{actions} = pack("v", (12 << 6) + $len) . $this->{actions};
}
my $sz = 8 + length($this->{hdr2}) + length($this->{bgcol}) + length($this->{actions}) + length($this->{end});
print "Content-type: application/x-shockwave-flash\n\n";
print $this->{hdr1} . pack("V", $sz) . $this->{hdr2} . $this->{bgcol} . $this->{actions} . $this->{end};
}
sub push
{ my $this = shift;
my $val = shift;
if($val =~ /^-?\d+$/)
{ $this->{push_action} .= "\7" . pack("V", $val & 0xffff);
}
elsif($val =~ /^-?(\d+|\d*\.\d+|\d+\.\d*)$/)
{ $this->{push_action} .= "\6" . pack("d", $val);
}
else
{ $this->{push_action} .= "\0" . $val . "\0";
}
}
sub addcode
{ my $this = shift;
my $op = shift;
my $l;
if($l = length($this->{push_action}))
{ $this->{actions} .= PUSHDATA . pack("v", $l) . $this->{push_action};
$this->{push_action} = '';
}
$this->{actions} .= $op;
}
sub setvar
{ my $this = shift;
my $name = shift;
my $val = shift;
my $member = $this->pushname($name);
$this->pushdata($val);
$this->addcode($member ? SETMEMBER : SETVAR);
}
sub call
{ my $this = shift;
my $name = shift;
my $nargs = $#_;
my $n;
for($n = $nargs ; $n >= 0 ; $n--)
{ $this->pushdata($_[$n]);
}
$this->push($nargs+1);
my $member = $this->pushname($name);
$this->addcode($member ? CALLMETHOD : CALLFUNCTION);
$this->addcode(POP);
}
sub pushname
{ my $this = shift;
my $name = shift;
my $member;
my @nameparts = split /\./, $name;
$member = $#nameparts > 0;
$this->push($nameparts[0]);
for($n = 1 ; $n <= $#nameparts ; $n++)
{ $this->addcode(($n == 1) ? GETVAR : GETMEMBER);
$this->push($nameparts[$n]);
}
return $member;
}
sub pushdata
{ my $this = shift;
my $val = shift;
my $n;
if(ref $val eq 'ARRAY')
{ for($n = $#$val ; $n >= 0 ; $n--)
{ if(exists $$val[$n])
{ $this->pushdata($$val[$n]);
}
else
{ $this->push_action .= "\3";
}
}
$this->push($#$val+1);
$this->addcode(INITARRAY);
}
elsif(ref $val eq 'HASH')
{ my @keys = keys %$val;
foreach $key (@keys)
{ $this->push($key);
$this->pushdata($$val{$key});
}
$this->push($#keys + 1);
$this->addcode(INITOBJECT);
}
else
{ $this->push($val);
}
}
package main;
$m = new swfdata();
$m->setvar('_root.data.counter', [23, 25]);
$m->call('_root.starter', 2.7, ['a', 'b', {'aa'=>11, 'bb'=>'unfug', 'cc'=>0}, 'd']);
$m->send();
Back