our
$VERSION
=
'0.0078'
;
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 {
my
(
$this
) =
@_
;
$this
->{string} =
""
;
$this
->{scene} = [];
return
;
}
sub
update_progress {
my
$pos
=
pos
(
$_
[0]->{string} ) || 0;
$_
[0]->progress(
$pos
/
length
(
$_
[0]->{string} ) );
$_
[0]->processEvents;
}
sub
parseString {
my
(
$this
,
$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;
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
;
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
) {
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;
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
) {
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 ) {
$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;
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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
) {
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;
}
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
);
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 '{'"
;
}
}
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
;
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
;
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
) {
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;
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;
}
}
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
;
}
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'
;
}
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
;
}
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
;
}
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;