package SOAP::WSDL::Deserializer::XSD_XS;
use strict;
use warnings;
use base qw(SOAP::WSDL::Deserializer::XSD);
use Class::Std::Fast::Storable;
use SOAP::WSDL::Expat::MessageParser_XS;

our $VERSION=0.1;

my $parser = SOAP::WSDL::Expat::MessageParser_XS->new();

sub deserialize {
    my ($self, $content) = @_;

    $parser->class_resolver( $self->get_class_resolver() );
    eval { $parser->parse_string( $content ) };
    if ($@) {
        return $self->generate_fault({
            code => 'soap:Server',
            role => 'urn:localhost',
            message => "Error deserializing message: $@. \n"
                . "Message was: \n$content"
        });
    }
    return ( $parser->get_data(), $parser->get_header() );
}

1;

=head1 NAME

SOAP::WSDL::Deserializer::XSD_XS - Fast XS based deserializer for SOAP-WSDL

=head1 DESCRIPTION

Fast XS based deserializer for SOAP::WSDL::Client and interface classes
generated by SOAP::WSDL. Converts SOAP messages to
SOAP::WSDL::XSD::Typlib:: based objects.

Needs a class_resolver typemap either passed by the generated interface
or user-provided.

SOAP::WSDL::DeserializerXSD_XS classes implement the API described in
L<SOAP::WSDL::Factory::Deserializer>.

=head1 USAGE

You need to use and register SOAP::WSDL_XS's Deserializer like this:

 use SOAP::WSDL::Deserializer::XSD_XS;
 use SOAP::WSDL::Factory::Deserializer;
 # register for SOAP 1.1
 SOAP::Factory::Deserializer->register('1.1' => 'SOAP::WSDL::Deserializer::XSD_XS' );

Registering a new serializer is a global setting - it affects all SOAP::WSDL
objects created after registration.

=head1 METHODS

=head2 deserialize

Deserializes the message.

=head2 generate_fault

Generates a L<SOAP::WSDL::SOAP::Typelib::Fault11|SOAP::WSDL::SOAP::Typelib::Fault11>
object and returns it.

=head1 PERFORMANCE

SOAP::WSDL_XS' deserializer reaches around 5x the performance of SOAP::WSDL's
XML deserializer and is a magnitude faster than SOAP::Lite's dezerializer.

Creating a DOM tree using XML::LibXML is around 4 times faster, but not
completely compareable - you pay a slight penalty for each XML::LibXML DOM
value-acces later. Converting a XML::LibXML DOM to a hash yields approximately
SOAP::WSDL's performance.

All benchmarks quoted below are part of the SOAP-WSDL distribution.
All results computed on a ThinkPad T42 equipped with a Pentium Mobile (Dothan)
at 1.7GHz and 1GB RAM running Ubuntu 7.4 and perl-5.8.8. Note that
benchmarking is not an exact science - results may vary due to side
conditions. Run your own benchmark when in question.

On a sample SOAP message of 6075 bytes, parser throughput (without
object destruction) is

                         Rate
  SOAP::Lite             61.9/s
  XML::LibXML (dom2hash)  267/s
  SOAP::WSDL              268/s
  SOAP::WSDL (Hash)       391/s
  SOAP::WSDL_XS          1087/s
  XML::LibXML (C DOM)    4054/s

A second benchmark shows the effect of caching and the offload of work to the
destructor in SOAP::WSDL's Class::Std::Fast based objects.

 XML length (bytes): 12730
 SOAP::Lite - 0.70_03
 SOAP::WSDL - 2.00_27
 SOAP::WSDL_XS - 0.00_1;
 XML::Compile::SOAP - 0.64
 XML::Simple - 2.16

 Benchmark 0: Store result in private variable and destroy it
               Rate   SOAP::Lite XML::Compile SOAP::WSDL XML::Simple WSDL_XS
 SOAP::Lite    25.5/s      --       -28%       -58%        -60%        -77%
 XML::Compile  35.4/s     39%         --       -41%        -44%        -68%
 SOAP::WSDL    60.4/s    137%        70%         --         -4%        -45%
 XML::Simple   63.0/s    147%        78%         4%          --        -42%
 WSDL_XS        109/s    328%       208%        81%         73%          --

 Benchmark 1: Push result on list
               Rate    SOAP::Lite XML::Compile SOAP::WSDL XML::Simple WSDL_XS
 SOAP::Lite     25.5/s      --      -29%        -59%       -71%        -93%
 XML::Compile   36.1/s     42%        --        -43%       -59%        -89%
 XML::Simple    62.8/s    146%       74%          --       -29%        -82%
 SOAP::WSDL     89.0/s    249%      146%         42%         --        -74%
 WSDL_XS        340/s   1235%      842%        441%       282%          --

 Benchmark 2: Play it again, Sam
               Rate   SOAP::Lite XML::Compile SOAP::WSDL XML::Simple WSDL_XS
 SOAP::Lite    25.5/s      --       -29%        -59%       -75%        -94%
 XML::Compile  35.7/s     40%         --        -43%       -64%        -92%
 XML::Simple   62.4/s    145%        75%          --       -38%        -86%
 SOAP::WSDL     100/s    294%       181%         61%         --        -78%
 WSDL_XS        446/s   1652%      1151%        615%       345%          --

SOAP::WSDL_XS trades speed for features, however - see the list of
limitations below.

=head1 BUGS AND LIMITATIONS

=over

=item * All XML elements must be namespace-qualified

SOAP::WSDL_XS's serializer will croak on non-namespace qualified XML elements.
This is a SOAP requirement, too.

=item * SOAP Header is not supported yet

There's no support for the SOAP Header yet.

=back

=head1 LICENSE AND COPYRIGHT

Copyright 2004-2009 Martin Kutter.

This file is part of SOAP-WSDL_XS. You may distribute/modify it under
the same terms as perl itself.

=head1 AUTHOR

Martin Kutter E<lt>martin.kutter fen-net.deE<gt>

=head1 REPOSITORY INFORMATION

 $Rev: 412 $
 $LastChangedBy: kutterma $
 $Id: XSD.pm 412 2007-11-27 22:57:52Z kutterma $
 $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/XSD.pm $

=cut
