From a22971308c9a0bfe8f403b3ced48cbb7ba17de79 Mon Sep 17 00:00:00 2001 From: Ian Beckwith Date: Wed, 6 Oct 2010 02:11:37 +0100 Subject: [PATCH] partial support for tag expression as binary tree --- lib/ID3FS/Path.pm | 55 ++++++++++++++++++++++++++++++++++++++++++++++ lib/ID3FS/Path/Node.pm | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 lib/ID3FS/Path/Node.pm diff --git a/lib/ID3FS/Path.pm b/lib/ID3FS/Path.pm index de55ce1..0ca6711 100644 --- a/lib/ID3FS/Path.pm +++ b/lib/ID3FS/Path.pm @@ -8,11 +8,14 @@ use ID3FS::PathElement::Boolean; use ID3FS::PathElement::File; use ID3FS::PathElement::Tag; use ID3FS::PathElement::Tagval; +use ID3FS::Path::Node; our ($STATE_INVALID, $STATE_ROOT, $STATE_TAG, $STATE_TAGVAL, $STATE_BOOLEAN, $STATE_ALBUMS, $STATE_TRACKLIST, $STATE_FILE)=(0..7); +our %priorities=( "OR" => 0, "AND" => 1, "NOT" => 2 ); + sub new { my $proto=shift; @@ -294,6 +297,7 @@ sub parse $self->state($STATE_INVALID); } } + $self->{tagtree}=$self->elements_to_tree(@{$self->{elements}}); } sub state @@ -303,4 +307,55 @@ sub state return $self->{state}; } +sub elements_to_tree +{ + my($self, @elements)=@_; + my $op=undef; + my $top=undef; + my $node=undef; + my $lastop=undef; + use Data::Dumper; + while(my $element=shift @elements) + { + my $tag; + if(ref($element) eq "ID3FS::PathElement::Boolean") + { + $lastop=$op; + $op=$element->{name}; +# print "BOOL: $op\n"; + } + if(ref($element) eq "ID3FS::PathElement::Tag") + { + $tag=$element->{name}; + while(@elements && ref($elements[0]) eq "ID3FS::PathElement::Tag") + { + $tag .= "/" . (shift @elements)->{name}; + } +# print "TAG: $tag\n"; + my $node=ID3FS::Path::Node->new($tag); + if(!$top) + { + $top=$node; + } + elsif($op) + { + my $nextop=undef; + if(!defined($lastop) || ($priorities{$lastop} >= $priorities{$op})) + { + $top=ID3FS::Path::Node->new($node, $op, $top); + } + else + { + $top=ID3FS::Path::Node->new($top, $op, $node); + } + } + else + { + die ("FAIL - SHOULD NOT HAPPEN\n"); + } + } + } + print($top->print(), "\n") if $top; +} + 1; diff --git a/lib/ID3FS/Path/Node.pm b/lib/ID3FS/Path/Node.pm new file mode 100644 index 0000000..08c2088 --- /dev/null +++ b/lib/ID3FS/Path/Node.pm @@ -0,0 +1,59 @@ +package ID3FS::Path::Node; + +use strict; +use warnings; + +sub new +{ + my $proto=shift; + my $class=ref($proto) || $proto; + my $self={}; + bless($self,$class); + + $self->left(shift); + $self->op(shift); + $self->right(shift); + + return $self; +} + +sub set +{ + my($self, $name, $val)=@_; + if(defined($val)) + { + $self->{$name}=$val; + } + return $self->{$name}; +} + +sub left { return shift->set("left", shift); } +sub right { return shift->set("right", shift); } +sub op { return shift->set("op", shift); } + +sub print +{ + my($self)=@_; + my $op=$self->op(); + my $left=$self->left(); + my $right=$self->right(); + return undef unless($left || $right); + my $str .= $self->print_node($left); + $str .= " $op " if($op); + $str .= $self->print_node($right); + if($op || ($left && $right)) + { + $str="(" . $str . ")"; + } + return $str; +} + +sub print_node +{ + my($self, $node)=@_; + return "" unless(defined($node)); + return $node->print() if(ref($node) eq "ID3FS::Path::Node"); + return $node; +} + +1; -- 2.11.0