use strict ;

package LDOdemoDecoder ;
use vars qw(@ISA) ;
use XML::Parser::Notifier::SimpleDispatcher ;
@ISA = qw(XML::Parser::Notifier::SimpleDispatcher) ;

my %Rules = (
    atom => \&atom,
    list => \&list,
    ref => \&Ref,
    dictionary => \&dict
) ;

sub Init {
    my $self = shift ;
    $self -> {Seen_} = {} ;
    $self -> _rules( {
        atom => \&atom,
        list => \&list,
        dictionary => \&dict,
        '#cont' => sub { $self -> {value} = $_[2] }
    } ) ;
}

sub Final { 
    $_[0] -> {value} 
}

sub list {
    my ($self, %atts) = @_ ;
    my $list = [] ;
    defined $atts{id} 
and $self -> {Seen_} -> {$atts{id}} = $list ;
    return {
        %Rules,
        '#end' => sub { $list },
        '#cont' => sub { push @$list, $_[2] }
    }
}

sub atom {
    my ($self, %atts) = @_ ;
    my $text = '' ;
    defined $atts{id} 
and $self -> {Seen_} -> {$atts{id}} = \$text ;
    return {
        '#char' => sub { $text .= $_[1] },
        '#end' => sub { $text }
    }

}

sub dict {
    my ($self, %atts) = @_ ;
    my $list = [] ;
    defined $atts{id} 
and $self -> {Seen_} -> {$atts{id}} = $list ;
    return {
        %Rules,
        '#end' => sub { return {@$list} },
        '#cont' => sub { push @$list, $_[2] }
    }
}

sub Ref {
    my ($self, %atts) = @_ ;
    my $iref = $atts{iref} 
 or die "Ref without iref!" ;
    my $deref = $self -> {Seen_} -> {$iref} ;
    ref($deref) eq 'SCALAR' 
and $deref = $$deref ;
    return { 
        '#end' => sub { $_[0] -> {value} = $deref } 
    }
}

1;


