package Weed::Parser;
our $VERSION = '0.0078';
use Carp qw(croak);
our $FieldDefinitions = [
new X3DFieldDefinition( initializeOnly, 'name', new SFString("X3D VRML Parser") ),
new X3DFieldDefinition( initializeOnly, 'version', new SFString("0.01") ),
new X3DFieldDefinition( outputOnly, 'progress', new SFFloat(0) ),
new X3DFieldDefinition( outputOnly, 'isActive', FALSE ),
];
sub initialize { #X3DError::Debug;
my ($this) = @_;
$this->{string} = "";
$this->{scene} = [];
#$this->getField("progress")->addFieldCallback( "println", $this->getBrowser );
return;
}
sub update_progress {
my $pos = pos( $_[0]->{string} ) || 0;
$_[0]->progress( $pos / length( $_[0]->{string} ) );
$_[0]->processEvents;
}
sub parseString {
my ( $this, $string ) = @_;
#X3DError::Debug length $string;
$this->progress(0);
$this->isActive(TRUE);
$this->processEvents;
$this->{string} = $string;
my $scene = $this->scene;
$this->progress(1);
$this->isActive(FALSE);
$this->processEvents;
return $scene;
}
sub createScene {
my ( $this, $profileDeclaration, $componentDeclaration ) = @_;
my $scene = new X3DScene;
$scene->profile($profileDeclaration);
$scene->components(@$componentDeclaration);
$scene->call( "setBrowser", $this->getBrowser );
$scene->call("initialize");
return $scene;
}
sub scene {
my ($this) = @_;
my $header = $this->headerStatement;
my $profileStatement = $this->profileStatement;
my $componentStatements = $this->componentStatements;
my $scene = $this->createScene( $profileStatement, $componentStatements );
if ( ref $scene ) {
unshift @{ $this->{scene} }, $scene;
my $metadataStatements = $this->metadataStatements;
$scene->encoding("VRML");
eval { $this->statements };
$this->getError;
shift @{ $this->{scene} };
return $scene;
}
return;
}
sub getError {
my ($this) = @_;
$this->{string} =~ m/\G$_whitespace*$/sgco; # spaces at end of string$
my $pos = pos( $this->{string} ) || 0;
return unless length( $this->{string} ) - $pos;
unless ($@) {
$this->{string} =~ m/\G$_whitespace*/sgco;
$pos = pos( $this->{string} ) || 0;
}
my $start = rindex( $this->{string}, "\n", $pos ) + 1;
my $end = index( $this->{string}, "\n", $start );
my $line = substr $this->{string}, $start, $end - $start;
my $begin = substr $this->{string}, 0, $pos;
my $lineNumber = ( $begin =~ s/\n/\n/sgo ) + 1;
eval { X3DError::UnknownStatement $line } unless $@;
X3DError::carp "*" x 80;
X3DError::carp "Parser error at - line $lineNumber:";
X3DError::carp $`; # $`
X3DError::carp $' unless $line; # $'
X3DError::carp "$line";
X3DError::carp " " x ( $pos - $start ) . "^";
X3DError::carp $@;
X3DError::carp "*" x 80;
$@ = "";
return;
}
sub getScene {
my ($this) = @_;
return $this->{scene}->[0];
}
sub headerStatement {
my ($this) = @_;
return;
}
sub profileStatement {
my ($this) = @_;
if ( $this->{string} =~ m/$_PROFILE/gc ) {
my $profileNameId = $this->profileNameId;
return $profileNameId if defined $profileNameId;
}
return "Core";
}
sub componentStatements {
my ($this) = @_;
my $componentStatement = $this->componentStatement;
my $componentStatements = [];
while ( defined $componentStatement ) {
push @$componentStatements, $componentStatement;
$componentStatement = $this->componentStatement;
}
return $componentStatements;
}
sub componentStatement {
my ($this) = @_;
return unless $this->{string} =~ m/$_COMPONENT/gc;
my $componentNameId = $this->componentNameId;
if ( defined $componentNameId ) {
my $componentSupportLevel = $this->componentSupportLevel;
if ( defined $componentSupportLevel ) {
return $componentNameId;
}
}
return;
}
sub metadataStatements {
my ($this) = @_;
my $metadataStatement = $this->metadataStatement;
while ( ref $metadataStatement ) {
$this->getScene->setMetaData(@$metadataStatement);
$metadataStatement = $this->metadataStatement;
}
return;
}
sub metadataStatement {
my ($this) = @_;
return unless $this->{string} =~ m/$_META/gc;
my $metakey = $this->metakey;
if ( defined $metakey ) {
my $metavalue = $this->metavalue;
if ( defined $metavalue ) {
return [ $metakey, $metavalue ];
}
}
return;
}
sub statements {
my $this = shift;
1 while $this->statement;
return;
}
sub statement {
my $this = shift;
#$this->update_progress;
my $nodeStatement = $this->nodeStatement;
return push @{ $this->getScene->rootNodes }, $nodeStatement if ref $nodeStatement;
return 1 if ref $this->protoStatement;
return 1 if ref $this->routeStatement;
return;
}
sub nodeStatement {
my $this = shift;
if ( $this->{string} =~ m/$_DEF/gc ) {
my $nodeNameId = $this->nodeNameId;
if ( defined $nodeNameId ) {
#X3DError::Debug "VRML2::Parser::nodeStatement DEF $nodeNameId\n";
my $node = $this->node($nodeNameId);
return $node if ref $node;
X3DError::Error "Premature end of file after DEF";
} else {
X3DError::Error "No name given after DEF";
}
}
if ( $this->{string} =~ m/$_USE/gc ) {
my $nodeNameId = $this->nodeNameId;
#X3DError::Debug "VRML2::Parser::nodeStatement USE $nodeNameId\n";
if ( defined $nodeNameId ) {
my $sfnode = $this->getScene->getNamedNode($nodeNameId);
return $sfnode->copy if ref $sfnode;
X3DError::Error "Unknown reference '$nodeNameId'";
} else {
X3DError::Error "Expected nodeNameId after USE";
}
}
my $node = $this->node;
return $node if ref $node;
return;
}
sub rootNodeStatement {
my $this = shift;
if ( $this->{string} =~ m/$_DEF/gc ) {
my $nodeNameId = $this->nodeNameId;
if ( defined $nodeNameId ) {
#X3DError::Debug "VRML2::Parser::rootNodeStatement $nodeNameId\n";
my $node = $this->node($nodeNameId);
if ( ref $node ) {
return $node;
} else {
X3DError::Error "Premature end of file after DEF";
}
} else {
X3DError::Error "No name given after DEF";
}
}
my $node = $this->node;
return $node if ref $node;
return;
}
sub protoStatement {
my $this = shift;
my $proto;
$proto = $this->proto;
unless ( ref $proto ) {
$proto = $this->externproto;
}
if ( ref $proto ) {
$this->addProto($proto);
return $proto;
}
return;
}
sub protoStatements {
my $this = shift;
my $protoStatement = $this->protoStatement;
my $protoStatements = [];
while ( ref $protoStatement ) {
push @$protoStatements, $protoStatement;
$protoStatement = $this->protoStatement;
}
return $protoStatements;
}
sub proto {
my $this = shift;
if ( $this->{string} =~ m/$_PROTO/gc ) {
my $nodeTypeId = $this->nodeTypeId;
if ( defined $nodeTypeId ) {
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $interfaceDeclarations = $this->interfaceDeclarations;
if (@$interfaceDeclarations) {
if ( $this->{string} =~ m/$_close_bracket/gc ) {
if ( $this->{string} =~ m/$_open_brace/gc ) {
my $proto =
new VRML2::Proto( $this->{parent}, $nodeTypeId,
$interfaceDeclarations );
$this->{parent} = $proto;
my $protoBody = $this->protoBody;
$this->{parent} = $proto->getParent;
if ( $this->{string} =~ m/$_close_brace/gc ) {
#X3DError::Debug "VRML2::Parser::proto $nodeTypeId done\n";
$proto->setBody($protoBody);
return $proto;
} else {
X3DError::Error "Expected a '}' to end prototype definition";
}
} else {
X3DError::Error "Expected a '{' to begin prototype definition";
}
} else {
X3DError::Error "Expected a ']'";
}
}
} else {
X3DError::Error "Expected a '['";
}
} else {
X3DError::Error "Invalid prototype definition name";
}
}
return;
}
sub protoBody {
my $this = shift;
my $protoBody = [ undef, undef, undef ];
$protoBody->[0] = $this->protoStatements;
$protoBody->[1] = $this->rootNodeStatement;
$protoBody->[2] = $this->statements;
#X3DError::Debug "VRML2::Parser::protoBody done\n";
return $protoBody;
}
sub interfaceDeclarations {
my $this = shift;
my $interfaceDeclaration = $this->interfaceDeclaration;
my $interfaceDeclarations = [];
while ( ref $interfaceDeclaration ) {
push @$interfaceDeclarations, $interfaceDeclaration;
$interfaceDeclaration = $this->interfaceDeclaration;
}
return $interfaceDeclarations;
}
sub restrictedInterfaceDeclaration {
my $this = shift;
if ( $this->{string} =~ m/$_eventIn/gc ) {
my $fieldType = $this->fieldType;
if ($fieldType) {
my $eventInId = $this->eventInId;
if ( defined $eventInId ) {
#X3DError::Debug "VRML2::Parser::restrictedInterfaceDeclaration eventIn $fieldType $eventInId\n";
return new eventIn( $fieldType, $eventInId );
} else {
X3DError::Error "Expected name for field";
}
} else {
X3DError::Error "Unknown event or field type: '", $this->Id, "'";
}
}
if ( $this->{string} =~ m/$_eventOut/gc ) {
my $fieldType = $this->fieldType;
if ($fieldType) {
my $eventOutId = $this->eventOutId;
if ( defined $eventOutId ) {
#X3DError::Debug "VRML2::Parser::restrictedInterfaceDeclaration eventOut $fieldType $eventOutId\n";
return new eventOut( $fieldType, $eventOutId );
} else {
X3DError::Error "Expected name for field";
}
} else {
X3DError::Error "Unknown event or field type: '", $this->Id, "'";
}
}
if ( $this->{string} =~ m/$_field/gc ) {
my $fieldType = $this->fieldType;
if ($fieldType) {
my $fieldId = $this->fieldId;
if ( defined $fieldId ) {
my $fieldValue = $this->fieldValue($fieldType);
if ( ref $fieldValue ) {
#X3DError::Debug "VRML2::Parser::restrictedInterfaceDeclaration field $fieldType $fieldId $fieldValue\n";
return new field( $fieldType, $fieldId, $fieldValue );
} else {
X3DError::Error "Couldn't read value for field '", $fieldId, "'";
}
} else {
X3DError::Error "Expected name for field";
}
} else {
X3DError::Error "Unknown event or field type: '", $this->Id, "'";
}
}
return;
}
sub interfaceDeclaration {
my $this = shift;
my $restrictedInterfaceDeclaration = $this->restrictedInterfaceDeclaration;
return $restrictedInterfaceDeclaration if ref $restrictedInterfaceDeclaration;
if ( $this->{string} =~ m/$_exposedField/gc ) {
my $fieldType = $this->fieldType;
if ($fieldType) {
my $fieldId = $this->fieldId;
if ( defined $fieldId ) {
my $fieldValue = $this->fieldValue($fieldType);
if ( ref $fieldValue ) {
#X3DError::Debug "VRML2::Parser::interfaceDeclaration exposedField $fieldType $fieldId $fieldValue\n";
return new exposedField( $fieldType, $fieldId, $fieldValue );
} else {
X3DError::Error "Couldn't read value for field '", $fieldId, "'";
}
} else {
X3DError::Error "Expected name for field";
}
} else {
X3DError::Error "Unknown event or field type: '", $this->Id, "'";
}
}
return;
}
sub externproto {
my $this = shift;
if ( $this->{string} =~ m/$_EXTERNPROTO/gc ) {
my $nodeTypeId = $this->nodeTypeId;
if ( defined $nodeTypeId ) {
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $externInterfaceDeclarations = $this->externInterfaceDeclarations;
if (@$externInterfaceDeclarations) {
if ( $this->{string} =~ m/$_close_bracket/gc ) {
my $URLList = $this->URLList;
if ( ref $URLList ) {
my $proto =
new VRML2::Proto( $this->{parent}, $nodeTypeId,
$externInterfaceDeclarations );
$proto->setURL($URLList);
return $proto;
} else {
X3DError::Error "Expected URL list in EXTERNPROTO $nodeTypeId";
}
} else {
X3DError::Error "Expected a ']'";
}
}
} else {
X3DError::Error "Expected a '['";
}
} else {
X3DError::Error "Invalid prototype definition name";
}
}
return;
}
sub externInterfaceDeclarations {
my $this = shift;
my $externInterfaceDeclaration = $this->externInterfaceDeclaration;
my $externInterfaceDeclarations = [];
while ( ref $externInterfaceDeclaration ) {
push @$externInterfaceDeclarations, $externInterfaceDeclaration;
$externInterfaceDeclaration = $this->externInterfaceDeclaration;
}
return $externInterfaceDeclarations;
}
sub externInterfaceDeclaration {
my $this = shift;
if ( $this->{string} =~ m/$_eventIn/gc ) {
my $fieldType = $this->fieldType;
if ($fieldType) {
my $eventInId = $this->eventInId;
if ( defined $eventInId ) {
#X3DError::Debug "VRML2::Parser::externInterfaceDeclaration eventIn $fieldType $eventInId\n";
return new eventIn( $fieldType, $eventInId );
} else {
X3DError::Error "Expected name for field";
}
} else {
X3DError::Error "Unknown event or field type: '", $this->Id, "'";
}
}
if ( $this->{string} =~ m/$_eventOut/gc ) {
my $fieldType = $this->fieldType;
if ($fieldType) {
my $eventOutId = $this->eventOutId;
if ( defined $eventOutId ) {
#X3DError::Debug "VRML2::Parser::externInterfaceDeclaration eventOut $fieldType $eventOutId\n";
return new eventOut( $fieldType, $eventOutId );
} else {
X3DError::Error "Expected name for field";
}
} else {
X3DError::Error "Unknown event or field type: '", $this->Id, "'";
}
}
if ( $this->{string} =~ m/$_field/gc ) {
my $fieldType = $this->fieldType;
if ($fieldType) {
my $fieldId = $this->fieldId;
if ( defined $fieldId ) {
#X3DError::Debug "VRML2::Parser::externInterfaceDeclaration field $fieldType $fieldId\n";
return new field( $fieldType, $fieldId, );
} else {
X3DError::Error "Expected name for field";
}
} else {
X3DError::Error "Unknown event or field type: '", $this->Id, "'";
}
}
if ( $this->{string} =~ m/$_exposedField/gc ) {
my $fieldType = $this->fieldType;
if ($fieldType) {
my $fieldId = $this->fieldId;
if ( defined $fieldId ) {
#X3DError::Debug "VRML2::Parser::externInterfaceDeclaration exposedField $fieldType $fieldId\n";
return new exposedField( $fieldType, $fieldId, );
} else {
X3DError::Error "Expected name for field";
}
} else {
X3DError::Error "Unknown event or field type: '", $this->Id, "'";
}
}
return;
}
sub routeStatement {
my $this = shift;
if ( $this->{string} =~ m/$_ROUTE/gc ) {
if ( $this->{string} =~ m/$_Id/gc ) {
my $fromNodeId = $1;
my $fromNode = $this->getScene->getNamedNode($fromNodeId);
if ( ref $fromNode ) {
if ( $this->{string} =~ m/$_period/gc ) {
if ( $this->{string} =~ m/$_Id/gc ) {
my $eventOutId = $1;
if ( $this->{string} =~ m/$_TO/gc ) {
if ( $this->{string} =~ m/$_Id/gc ) {
my $toNodeId = $1;
my $toNode = $this->getScene->getNamedNode($toNodeId);
if ( ref $toNode ) {
if ( $this->{string} =~ m/$_period/gc ) {
if ( $this->{string} =~ m/$_Id/gc ) {
my $eventInId = $1;
return $this->getScene->addRoute( $fromNode,
$eventOutId, $toNode, $eventInId );
} else {
X3DError::BadRouteSpecification;
}
} else {
X3DError::BadRouteSpecification;
}
} else {
X3DError::BadRouteSpecification;
}
} else {
X3DError::BadRouteSpecification;
}
} else {
X3DError::BadRouteSpecification;
}
} else {
X3DError::BadRouteSpecification;
}
} else {
X3DError::BadRouteSpecification;
}
} else {
X3DError::BadRouteSpecification;
}
}
}
return;
}
sub URLList {
my $this = shift;
return $this->mfstringValue;
}
# Nodes
sub node {
my $this = shift;
my $nodeNameId = shift;
if ( $this->{string} =~ m/$_NodeTypeId/gc ) {
my $type = $1;
if ( $this->{string} =~ m/$_open_brace/gc ) {
my $comments = $this->comments;
my $sfnode = $this->getScene->createNode( $type, $nodeNameId, $comments );
#X3DError::Debug $sfnode->getReferenceCount;
if ( ref $sfnode ) {
my $node = $sfnode->getValue;
my $fields;
if ( $type eq 'Script' ) {
$fields = $this->scriptBody($node);
} else {
$fields = $this->nodeBody($node);
}
if ( $this->{string} =~ m/$_close_brace/gc ) {
$node->call( "setFields", $fields );
$node->call("initialize");
return $sfnode;
} else {
X3DError::Error "Expected '}'";
}
} else {
X3DError::UnknownClass $type;
}
} else {
X3DError::Error "Expected '{'";
}
}
#X3DError::Debug "VRML2::Parser::node undef\n";
return;
}
sub nodeBody {
my $this = shift;
my $node = shift;
my $nodeBody = [];
my $nodeBodyElement = $this->nodeBodyElement($node);
while ( ref $nodeBodyElement ) {
push @$nodeBody, $nodeBodyElement if ref $nodeBodyElement;
$nodeBodyElement = $this->nodeBodyElement($node);
}
return $nodeBody;
}
sub scriptBody {
my $this = shift;
my $node = shift;
my $scriptBody = [];
my $scriptBodyElement = $this->scriptBodyElement($node);
while ( ref $scriptBodyElement ) {
push @$scriptBody, $scriptBodyElement if ref $scriptBodyElement;
$scriptBodyElement = $this->scriptBodyElement($node);
}
return $scriptBody;
}
sub scriptBodyElement {
my $this = shift;
my $node = shift;
if ( $this->{string} =~ m/$_ScriptNodeInterface_IS/gc ) {
my $fieldClass = $1;
my $fieldType = $2;
my $fieldId = $3;
my $field = { type => $fieldType, name => $fieldId };
bless $field, $fieldClass;
#X3DError::Debug "VRML2::Parser::scriptBodyElement", ref $field,"\n";
if ( ref $this->{parent} ne 'VRML2::Browser' ) {
my $is = $this->Id;
my $isField = $this->{parent}->getField($is);
if ( ref $isField ) {
if ( $field ge $isField ) {
if ( $field->getType eq $isField->getType ) {
return $field->new( $fieldType, $fieldId, $isField->getValue,
$isField );
} else {
X3DError::Error "Field ", $field->getName, " and ", $isField->getName,
" in PROTO ", $this->{parent}->getName, " have different types";
}
} else {
X3DError::Error "Field ", $field->getName, " and ", $isField->getName,
" in PROTO ", $this->{parent}->getName,
" are incompatible as an IS mapping";
}
} else {
X3DError::Error "No such event or field '$is' inside PROTO ",
$this->{parent}->getName, "";
}
} else {
X3DError::Error "IS statement outside PROTO definition";
}
}
my $restrictedInterfaceDeclaration = $this->restrictedInterfaceDeclaration;
return $restrictedInterfaceDeclaration if ref $restrictedInterfaceDeclaration;
my $nodeBodyElement = $this->nodeBodyElement($node);
return $nodeBodyElement if ref $nodeBodyElement;
return;
}
sub nodeBodyElement {
my $this = shift;
my $node = shift;
#X3DError::Debug "VRML2::Parser::nodeBodyElement\n";
my $protoStatement = $this->protoStatement;
return $protoStatement if ref $protoStatement;
my $routeStatement = $this->routeStatement;
return $routeStatement if ref $routeStatement;
my $fieldId = $this->fieldId;
if ( defined $fieldId ) {
#X3DError::Debug "VRML2::Parser::nodeBodyElement $fieldId\n";
my $field = $node->getField($fieldId);
if ( ref $field ) {
if ( $this->{string} =~ m/$_IS/gc ) {
if ( ref $this->{parent} ne 'VRML2::Browser' ) {
my $is = $this->Id;
#X3DError::Debug "VRML2::Parser::nodeBodyElement IS mapping", $is, "\n";
my $isField = $this->{parent}->getField($is);
if ( ref $isField ) {
if ( $field ge $isField ) {
if ( $field->getType eq $isField->getType ) {
return $field->new( $field->getType, $fieldId,
$isField->getValue, $isField );
} else {
X3DError::Error "Field ", $field->getName, " and ",
$isField->getName, " in PROTO ", $this->{parent}->getName,
" have different types";
}
} else {
X3DError::Error "Field ", $field->getName, " and ",
$isField->getName, " in PROTO ", $this->{parent}->getName,
" are incompatible as an IS mapping";
}
} else {
X3DError::Error "No such event or field '$is' inside PROTO ",
$this->{parent}->getName, "";
}
} else {
X3DError::Error "IS statement outside PROTO definition";
}
}
my $fieldValue = $this->fieldValue( $field->getType );
if ( ref $fieldValue ) {
$field->setValue($fieldValue);
return $field;
} else {
X3DError::Error "Couldn't read value for field '$fieldId'";
}
} else {
croak;
}
}
#X3DError::Debug "VRML2::Parser::nodeBodyElement undef\n";
return;
}
sub profileNameId {
my $this = shift;
return $this->Id;
}
sub componentNameId {
my $this = shift;
return $this->Id;
}
sub componentSupportLevel {
my $this = shift;
return $this->int32;
}
sub metakey {
my $this = shift;
return $this->string;
}
sub metavalue {
my $this = shift;
return $this->string;
}
sub nodeNameId {
my $this = shift;
return $this->Id;
}
sub nodeTypeId {
my $this = shift;
return $this->Id;
}
sub fieldId {
my $this = shift;
return $this->Id;
}
sub eventInId {
my $this = shift;
return $this->Id;
}
sub eventOutId {
my $this = shift;
return $this->Id;
}
sub Id {
my $this = shift;
return $1 if $this->{string} =~ m/$_Id/gc;
return;
}
sub comments {
my $this = shift;
my $comment = $this->comment;
my $comments = [];
while ( defined $comment ) {
push @$comments, $comment;
$comment = $this->comment;
}
return $comments;
}
sub comment {
my $this = shift;
return $1 if $this->{string} =~ m/$_comment/gc;
return;
}
# Fields
sub fieldType {
my $this = shift;
return $1 if $this->{string} =~ m/$_fieldType/gc;
return;
}
sub fieldValue {
my $this = shift;
my $fieldType = shift;
if ( index( $fieldType, 'SF' ) == 0 ) {
return $this->sfboolValue if $fieldType eq 'SFBool';
return $this->sfcolorValue if $fieldType eq 'SFColor';
return $this->sfdoubleValue if $fieldType eq 'SFDouble';
return $this->sffloatValue if $fieldType eq 'SFFloat';
return $this->sfimageValue if $fieldType eq 'SFImage';
return $this->sfint32Value if $fieldType eq 'SFInt32';
return $this->sfnodeValue if $fieldType eq 'SFNode';
return $this->sfrotationValue if $fieldType eq 'SFRotation';
return $this->sfstringValue if $fieldType eq 'SFString';
return $this->sftimeValue if $fieldType eq 'SFTime';
return $this->sfvec2dValue if $fieldType eq 'SFVec2d';
return $this->sfvec2fValue if $fieldType eq 'SFVec2f';
return $this->sfvec3dValue if $fieldType eq 'SFVec3d';
return $this->sfvec3fValue if $fieldType eq 'SFVec3f';
} else {
return $this->mfcolorValue if $fieldType eq 'MFColor';
return $this->mfdoubleValue if $fieldType eq 'MFDouble';
return $this->mffloatValue if $fieldType eq 'MFFloat';
return $this->mfint32Value if $fieldType eq 'MFInt32';
return $this->mfnodeValue if $fieldType eq 'MFNode';
return $this->mfrotationValue if $fieldType eq 'MFRotation';
return $this->mfstringValue if $fieldType eq 'MFString';
return $this->mftimeValue if $fieldType eq 'MFTime';
return $this->mfvec2fValue if $fieldType eq 'MFVec2f';
return $this->mfvec3fValue if $fieldType eq 'MFVec3f';
}
# if ( $this->{comment} =~ /$_CosmoWorlds/ ) {
# my $version = $1;
# return $this->sfenumValue if $fieldType eq 'SFEnum';
# return $this->mfenumValue if $fieldType eq 'MFEnum';
# }
return;
}
sub sfboolValue {
my $this = shift;
return new SFBool(1) if $this->{string} =~ m/$_TRUE/gc;
return new SFBool if $this->{string} =~ m/$_FALSE/gc;
return;
}
sub sfcolorValue {
my $this = shift;
my ( $r, $g, $b );
$r = $this->float;
if ( defined $r ) {
$g = $this->float;
if ( defined $g ) {
$b = $this->float;
if ( defined $b ) {
return new SFColor( $r, $g, $b );
}
}
}
return;
}
sub sfdoubleValue {
my $this = shift;
my $double = $this->float;
return new SFDouble($double) if defined $double;
return;
}
sub sffloatValue {
my $this = shift;
my $float = $this->float;
return new SFFloat($float) if defined $float;
return;
}
sub float {
my $this = shift;
return $1 if $this->{string} =~ m/$_float/gc;
return 0 if $this->{string} =~ m/$_nan/gc;
#return ... if $this->{string} =~ m/$_inf/gc;
#X3DError::Debug "VRML2::Parser::float undef\n";
return;
}
sub sfimageValue {
my $this = shift;
my ( $width, $height, $components );
my $pixels = [];
$width = $this->int32;
if ( defined $width ) {
$height = $this->int32;
if ( defined $height ) {
$components = $this->int32;
if ( defined $components ) {
my $size = $height * $width;
for ( my $i = 0 ; $i < $size ; ++$i ) {
my $pixel = $this->int32;
last unless defined $pixel;
push @$pixels, $pixel;
}
return new SFImage( $width, $height, $components, $pixels );
}
}
}
return;
}
sub sfint32Value {
my $this = shift;
my $int32 = $this->int32;
return new SFInt32($int32) if defined $int32;
return;
}
sub int32 {
my $this = shift;
return defined $2 ? hex($1) : $1 if $this->{string} =~ m/$_int32/gc;
return;
}
sub sfnodeValue {
my $this = shift;
my $nodeStatement = $this->nodeStatement;
return $nodeStatement if ref $nodeStatement;
return new SFNode if $this->{string} =~ m/$_NULL/gc;
return;
}
sub sfrotationValue {
my $this = shift;
my ( $x, $y, $z, $angle );
$x = $this->float;
if ( defined $x ) {
$y = $this->float;
if ( defined $y ) {
$z = $this->float;
if ( defined $z ) {
$angle = $this->float;
if ( defined $angle ) {
return new SFRotation( $x, $y, $z, $angle );
}
}
}
}
return;
}
sub sfstringValue {
my $this = shift;
my $string = $this->string;
return new SFString($string) if defined $string;
return;
}
sub string {
my $this = shift;
return $1 if $this->{string} =~ m/$_string/gc;
return;
}
sub sftimeValue {
my $this = shift;
my $time = $this->double;
return new SFTime($time) if defined $time;
return;
}
sub double {
my $this = shift;
return $1 if $this->{string} =~ m/$_double/gc;
return;
}
sub mftimeValue {
my $this = shift;
my $sftimeValue = $this->sftimeValue;
return new MFTime($sftimeValue) if ref $sftimeValue;
return new MFTime if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sftimeValues = $this->sftimeValues;
return new MFTime($sftimeValues)
if @$sftimeValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sftimeValues {
my $this = shift;
my $sftimeValue = $this->sftimeValue;
my $sftimeValues = [];
while ( ref $sftimeValue ) {
push @$sftimeValues, $sftimeValue;
$sftimeValue = $this->sftimeValue;
}
return $sftimeValues;
}
sub sfvec2fValue {
my $this = shift;
my ( $x, $y );
$x = $this->float;
if ( defined $x ) {
$y = $this->float;
if ( defined $y ) {
return new SFVec2f( $x, $y );
}
}
return;
}
sub sfvec2dValue {
my $this = shift;
my ( $x, $y );
$x = $this->double;
if ( defined $x ) {
$y = $this->double;
if ( defined $y ) {
return new SFVec2d( $x, $y );
}
}
return;
}
sub sfvec3fValue {
my $this = shift;
my ( $x, $y, $z );
$x = $this->float;
if ( defined $x ) {
$y = $this->float;
if ( defined $y ) {
$z = $this->float;
if ( defined $z ) {
return new SFVec3f( $x, $y, $z );
}
}
}
return;
}
sub sfvec3dValue {
my $this = shift;
my ( $x, $y, $z );
$x = $this->double;
if ( defined $x ) {
$y = $this->double;
if ( defined $y ) {
$z = $this->double;
if ( defined $z ) {
return new SFVec3d( $x, $y, $z );
}
}
}
return;
}
sub mfboolValue {
my $this = shift;
my $sfboolValue = $this->sfboolValue;
return new MFBool($sfboolValue) if ref $sfboolValue;
return new MFBool if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sfboolValues = $this->sfboolValues;
return new MFBool($sfboolValues)
if @$sfboolValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sfboolValues {
my $this = shift;
my $sfboolValue = $this->sfboolValue;
my $sfboolValues = [];
while ( ref $sfboolValue ) {
push @$sfboolValues, $sfboolValue;
$sfboolValue = $this->sfboolValue;
}
return $sfboolValues;
}
sub mfcolorValue {
my $this = shift;
my $sfcolorValue = $this->sfcolorValue;
return new MFColor($sfcolorValue) if ref $sfcolorValue;
return new MFColor if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sfcolorValues = $this->sfcolorValues;
return new MFColor($sfcolorValues)
if @$sfcolorValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sfcolorValues {
my $this = shift;
my $sfcolorValue = $this->sfcolorValue;
my $sfcolorValues = [];
while ( ref $sfcolorValue ) {
push @$sfcolorValues, $sfcolorValue;
$sfcolorValue = $this->sfcolorValue;
}
return $sfcolorValues;
}
sub mfdoubleValue {
my $this = shift;
my $sfdoubleValue = $this->sfdoubleValue;
return new MFDouble($sfdoubleValue) if ref $sfdoubleValue;
return new MFDouble if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sfdoubleValues = $this->sfdoubleValues;
return new MFDouble($sfdoubleValues)
if @$sfdoubleValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sfdoubleValues {
my $this = shift;
my $sfdoubleValue = $this->sfdoubleValue;
my $sfdoubleValues = [];
while ( ref $sfdoubleValue ) {
push @$sfdoubleValues, $sfdoubleValue;
$sfdoubleValue = $this->sfdoubleValue;
}
return $sfdoubleValues;
}
sub mffloatValue {
my $this = shift;
my $sffloatValue = $this->sffloatValue;
return new MFFloat($sffloatValue) if ref $sffloatValue;
return new MFFloat if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sffloatValues = $this->sffloatValues;
return new MFFloat($sffloatValues)
if @$sffloatValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sffloatValues {
my $this = shift;
my $sffloatValue = $this->sffloatValue;
my $sffloatValues = [];
while ( ref $sffloatValue ) {
push @$sffloatValues, $sffloatValue;
$sffloatValue = $this->sffloatValue;
}
return $sffloatValues;
}
sub mfint32Value {
my $this = shift;
my $sfint32Value = $this->sfint32Value;
return new MFInt32($sfint32Value) if ref $sfint32Value;
return new MFInt32 if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sfint32Values = $this->sfint32Values;
return new MFInt32($sfint32Values)
if @$sfint32Values && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sfint32Values {
my $this = shift;
my $sfint32Value = $this->sfint32Value;
my $sfint32Values = [];
while ( ref $sfint32Value ) {
push @$sfint32Values, $sfint32Value;
$sfint32Value = $this->sfint32Value;
}
return $sfint32Values;
}
sub mfnodeValue {
my $this = shift;
my $node = $this->nodeStatement;
return new MFNode($node) if ref $node;
return new MFNode if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $nodes = $this->nodeStatements;
return new MFNode($nodes)
if @$nodes && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub nodeStatements {
my $this = shift;
my $nodeStatement = $this->nodeStatement;
my $nodeStatements = [];
while ( ref $nodeStatement ) {
push @$nodeStatements, $nodeStatement;
$nodeStatement = $this->nodeStatement;
}
return $nodeStatements;
}
sub mfrotationValue {
my $this = shift;
my $sfrotationValue = $this->sfrotationValue;
return new MFRotation($sfrotationValue) if ref $sfrotationValue;
return new MFRotation if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sfrotationValues = $this->sfrotationValues;
return new MFRotation($sfrotationValues)
if @$sfrotationValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sfrotationValues {
my $this = shift;
my $sfrotationValue = $this->sfrotationValue;
my $sfrotationValues = [];
while ( ref $sfrotationValue ) {
push @$sfrotationValues, $sfrotationValue;
$sfrotationValue = $this->sfrotationValue;
}
return $sfrotationValues;
}
sub mfstringValue {
my $this = shift;
my $sfstringValue = $this->sfstringValue;
return new MFString($sfstringValue) if ref $sfstringValue;
return new MFString if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sfstringValues = $this->sfstringValues;
return new MFString($sfstringValues)
if @$sfstringValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sfstringValues {
my $this = shift;
my $sfstringValue = $this->sfstringValue;
my $sfstringValues = [];
while ( ref $sfstringValue ) {
push @$sfstringValues, $sfstringValue;
$sfstringValue = $this->sfstringValue;
}
return $sfstringValues;
}
sub mfvec2dValue {
my $this = shift;
my $sfvec2dValue = $this->sfvec2dValue;
return new MFVec2d($sfvec2dValue) if ref $sfvec2dValue;
return new MFVec2d if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sfvec2dValues = $this->sfvec2dValues;
return new MFVec2d($sfvec2dValues)
if @$sfvec2dValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sfvec2dValues {
my $this = shift;
my $sfvec2dValue = $this->sfvec2dValue;
my $sfvec2dValues = [];
while ( ref $sfvec2dValue ) {
push @$sfvec2dValues, $sfvec2dValue;
$sfvec2dValue = $this->sfvec2dValue;
}
return $sfvec2dValues;
}
sub mfvec2fValue {
my $this = shift;
my $sfvec2fValue = $this->sfvec2fValue;
return new MFVec2f($sfvec2fValue) if ref $sfvec2fValue;
return new MFVec2f if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sfvec2fValues = $this->sfvec2fValues;
return new MFVec2f($sfvec2fValues)
if @$sfvec2fValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sfvec2fValues {
my $this = shift;
my $sfvec2fValue = $this->sfvec2fValue;
my $sfvec2fValues = [];
while ( ref $sfvec2fValue ) {
push @$sfvec2fValues, $sfvec2fValue;
$sfvec2fValue = $this->sfvec2fValue;
}
return $sfvec2fValues;
}
sub mfvec3dValue {
my $this = shift;
my $sfvec3dValue = $this->sfvec3dValue;
return new MFVec3d($sfvec3dValue) if ref $sfvec3dValue;
return new MFVec3d if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sfvec3dValues = $this->sfvec3dValues;
return new MFVec3d($sfvec3dValues)
if @$sfvec3dValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sfvec3dValues {
my $this = shift;
my $sfvec3dValue = $this->sfvec3dValue;
my $sfvec3dValues = [];
while ( ref $sfvec3dValue ) {
push @$sfvec3dValues, $sfvec3dValue;
$sfvec3dValue = $this->sfvec3dValue;
}
return $sfvec3dValues;
}
sub mfvec3fValue {
my $this = shift;
my $sfvec3fValue = $this->sfvec3fValue;
return new MFVec3f($sfvec3fValue) if ref $sfvec3fValue;
return new MFVec3f if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sfvec3fValues = $this->sfvec3fValues;
return new MFVec3f($sfvec3fValues)
if @$sfvec3fValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sfvec3fValues {
my $this = shift;
my $sfvec3fValue = $this->sfvec3fValue;
my $sfvec3fValues = [];
while ( ref $sfvec3fValue ) {
push @$sfvec3fValues, $sfvec3fValue;
$sfvec3fValue = $this->sfvec3fValue;
}
return $sfvec3fValues;
}
# Fields CosmoWorlds
sub sfenumValue {
my $this = shift;
my $enum = $this->enum;
return new SFEnum($enum) if defined $enum;
}
sub enum {
my $this = shift;
return $1 if $this->{string} =~ m/$_enum/gc;
return;
}
sub mfenumValue {
my $this = shift;
my $sfenumValue = $this->sfenumValue;
return new MFEnum($sfenumValue) if ref $sfenumValue;
return new MFEnum if $this->{string} =~ m/$_brackets/gc;
if ( $this->{string} =~ m/$_open_bracket/gc ) {
my $sfenumValues = $this->sfenumValues;
return new MFEnum($sfenumValues)
if @$sfenumValues && $this->{string} =~ m/$_close_bracket/gc;
}
return;
}
sub sfenumValues {
my $this = shift;
my $sfenumValue = $this->sfenumValue;
my $sfenumValues = [];
while ( ref $sfenumValue ) {
push @$sfenumValues, $sfenumValue;
$sfenumValue = $this->sfenumValue;
}
return $sfenumValues;
}
1;
__END__
printf "%s\n", __PACKAGE__->new;