#!/usr/bin/perl use strict; use warnings; use Getopt::Std; use XML::SAX::Writer; use WAP::SAXDriver::wbxml; my %opts; getopts('b', \%opts); my $path = $INC{'WAP/SAXDriver/wbxml.pm'}; $path =~ s/wbxml\.pm$//i; $path .= 'syncml.wbrules2.pl'; my $consumer = new XML::SAX::Writer::StringConsumer(); my $handler = new XML::SAX::Writer(Writer => 'MyWriterXML', Output => $consumer); my $error = new MyErrorHandler(); my $parser = new WAP::SAXDriver::wbxml(Handler => $handler, ErrorHandler => $error, RulesPath => $path); my $file = $ARGV[0]; die "No input.\n" unless ($file); my $io = new IO::File($file, 'r'); die "Can't open $file ($!).\n" unless (defined $io); binmode $io, ':raw'; my $out = $ARGV[1]; if ($out) { open STDOUT, '>', $out or die "can't open $out ($!).\n"; } my $doc = $parser->parse( Source => {ByteStream => $io} ); if ($opts{b}) { print beautify(${$consumer->finalize()}); } else { print ${$consumer->finalize()}; } sub beautify { my $out = q{}; my @tab; foreach (split /(<[^>']*(?:'[^']*'[^>']*)*>)/, shift) { next unless ($_); pop @tab if (/^<\//); $out .= "@tab$_\n"; push @tab, ' ' if (/^<[^\/?!]/ and /[^\/]>$/); } return $out; } package MyErrorHandler; sub new { my $proto = shift; my $class = ref($proto) || $proto; return bless {}, $class; } sub fatal_error { my $self = shift; my ($hash) = @_; die __PACKAGE__,": Fatal error\n\tat position $hash->{BytePosition}.\n"; } sub error { my $self = shift; my ($hash) = @_; warn __PACKAGE__,": Error: $hash->{Message}\n\tat position $hash->{BytePosition}\n"; } sub warning { my $self = shift; my ($hash) = @_; warn __PACKAGE__,": Warning: $hash->{Message}\n\tat position $hash->{BytePosition}\n"; } package MyWriterXML; use base qw(XML::SAX::Writer::XML); sub characters { my $self = shift; my $data = shift; $self->_output_element; my $char = $data->{Data}; my $first = ord $char; if ($first <= 03) { # WBXML inner my $consumer = new XML::SAX::Writer::StringConsumer(); my $handler = new XML::SAX::Writer(Output => $consumer); my $error = new MyErrorHandler(); my $parser = new WAP::SAXDriver::wbxml(Handler => $handler, ErrorHandler => $error, RulesPath => $main::path); my $doc = $parser->parse( Source => {String => $char} ); if ($main::opts{b}) { $char = 'finalize()}) . ']]>'; } else { $char = 'finalize()} . ']]>'; } } else { if ($self->{InCDATA}) { # we must scan for ]]> in the CDATA and escape it if it # is present by close--opening # we need to have buffer text in front of this... $char = join ']]>]]<', $char; } else { $char = $self->escape($char); } } $char = $self->{Encoder}->convert($char); $self->{Consumer}->output($char); } __END__ =head1 NAME syncmld - SyncML Disassembler =head1 SYNOPSYS syncmld [B<-b>] I =head1 OPTIONS =over 8 =item -b Beautify =back =head1 DESCRIPTION B is derived from B. WAP Specifications, including Binary XML Content Format (WBXML) are available on Ehttp://www.wapforum.org/E. SyncML Specifications are available on Ehttp://www.syncml.org/E. =head1 SEE ALSO WAP::SAXDriver::wbxml, WAP::wbxml, wbxmlc, wbxmld =head1 AUTHOR Francois PERRAD, francois.perrad@gadz.org =cut