00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <vector>
00021 #include <map>
00022
00023 #include <archon/util/text.H>
00024 #include <archon/util/unicode.H>
00025
00026 #include <archon/x3d/server/script.H>
00027 #include <archon/x3d/server/parse.H>
00028
00029 using namespace std;
00030
00031 namespace Archon
00032 {
00033 using namespace Utilities;
00034
00035 namespace X3D
00036 {
00037 bool Parser::validateIdentifier(string s)
00038 {
00039 ustring t = Unicode::decodeUtf8(s);
00040 if(!t.size()) return false;
00041 for(unsigned i=0; i<t.size(); ++i)
00042 {
00043 uchar u = t[i];
00044 if(u >= 0x80) continue;
00045 if(u <= 0x20 ||
00046 i == 0 && '0' <= u && u <= '9' ||
00047 u == '"' || u == '#' || u == '\'' ||
00048 '+' <= u && u <= '.' ||
00049 '[' <= u && u <= ']' ||
00050 u == '{' || u == '}' || u == 0x7f)
00051 return false;
00052 }
00053 return true;
00054 }
00055
00056 void Parser::addNamedNode(string name, Ref<NodeBase> node)
00057 {
00058 try
00059 {
00060 node->setName(name);
00061 }
00062 catch(NodeNameInUseException &)
00063 {
00064 warning("Attempt to reuse node name '" + name + "'");
00065 }
00066 }
00067
00068 void Parser::addRootGroupChild(Ref<ChildNode> c, Time stamp)
00069 {
00070 rootGroup->add(GroupingNode::childrenField, c, stamp);
00071 }
00072
00073 void Parser::addRoute(string sourceNodeName, string sourceFieldName,
00074 string targetNodeName, string targetFieldName)
00075 {
00076 const FieldBase *sourceField = 0;
00077 const FieldBase *targetField = 0;
00078
00079 bool skip = false;
00080
00081 Ref<NodeBase> sourceNode = lookupNode(sourceNodeName);
00082 if(!sourceNode)
00083 {
00084 warning("Undefined source node name '" + sourceNodeName +
00085 "' (route ignored)");
00086 skip = true;
00087 }
00088 else
00089 {
00090 sourceField = sourceNode->lookupField(sourceFieldName);
00091 if(!sourceField)
00092 {
00093 warning("Source node type '" + sourceNode->getType()->getName() +
00094 "' has no field named '" + sourceFieldName +
00095 "' (route ignored)");
00096 skip = true;
00097 }
00098 else if(!sourceField->getIsEventSource())
00099 {
00100 warning(sourceNode->getType()->getName() + "." +
00101 sourceField->getName() +
00102 " cannot generate events (route ignored)");
00103 skip = true;
00104 }
00105 }
00106
00107 Ref<NodeBase> targetNode = lookupNode(targetNodeName);
00108 if(!targetNode)
00109 {
00110 warning("Undefined target node name '" + targetNodeName +
00111 "' (route ignored)");
00112 skip = true;
00113 }
00114 else
00115 {
00116 targetField = targetNode->lookupField(targetFieldName);
00117 if(!targetField)
00118 {
00119 warning("Target node type '" + targetNode->getType()->getName() +
00120 "' has no field named '" + targetFieldName +
00121 "' (route ignored)");
00122 skip = true;
00123 }
00124 else if(!targetField->getIsEventTarget())
00125 {
00126 warning(targetNode->getType()->getName() + "." +
00127 targetField->getName() +
00128 " cannot receive events (route ignored)");
00129 skip = true;
00130 }
00131 }
00132
00133
00134 if(sourceField && targetField &&
00135 sourceNode == targetNode && sourceField == targetField)
00136 {
00137 const string s = sourceNode->getName() + "." + sourceField->getName();
00138 warning("Illegal route, source field '" + s +
00139 "' and target field '" + s + "' is the same (route ignored)");
00140 skip = true;
00141 }
00142
00143 const FieldType *fieldType = 0;
00144
00145
00146 if(sourceField && targetField)
00147 {
00148 fieldType = sourceField->getType();
00149 const FieldType *targetFieldType = targetField->getType();
00150
00155 if(fieldType != targetFieldType)
00156 {
00157 warning("Type mismatch, source field type is '" +
00158 fieldType->getName() +
00159 "' and target field type is '" +
00160 targetFieldType->getName() + "' (route ignored)");
00161 skip = true;
00162 }
00163
00168 if(const NodeFieldBase *sourceNodeField =
00169 dynamic_cast<const NodeFieldBase *>(sourceField))
00170 {
00171 const NodeFieldBase *targetNodeField =
00172 dynamic_cast<const NodeFieldBase *>(targetField);
00173 if(!sourceNodeField->getNodeType()->
00174 isDerivedFrom(targetNodeField->getNodeType()))
00175 {
00176 warning("Type mismatch, source field type is '" +
00177 sourceNodeField->getNodeType()->getName() +
00178 "' and target field type is '" +
00179 targetNodeField->getNodeType()->getName() +
00180 "' (route ignored)");
00181 skip = true;
00182 }
00183 }
00184 }
00185
00186 if(skip) return;
00187
00188 Route::add(sourceNode, sourceField, targetNode, targetField);
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 }
00200
00201
00202 int Parser::getNextCustomFieldIndex(Ref<CustomFieldNode> n)
00203 {
00204 return n->getNumberOfCustomFields();
00205 }
00206
00207 void Parser::addScriptField(Ref<CustomFieldNode> n, Ref<CustomFieldBase> f)
00208 {
00209 if(!n->addCustomField(f))
00210 warning("Name of new field '" + f->getName() + "' clashes with "
00211 "existing fields of the " + n->getType()->getName() +
00212 " node (field ignored)");
00213 }
00214 }
00215 }