@@ -346,6 +346,27 @@ bool TokenFunc::isEnumeration(const Token& t) {
346346bool TokenFunc::isDatatype (const Token& t) {
347347 return ! isOperator (t) && startsWith (t, ' I' );
348348}
349+ bool TokenFunc::isInt (const Token& t) {
350+ if (isOperator (t)) return false ;
351+ const std::string str = asString (t);
352+ const char * start = str.c_str ();
353+ char * end;
354+ long result = strtol (start,&end,10 );
355+ return ((end - start) == str.length ());
356+ }
357+ bool TokenFunc::isBool (const Token& t) {
358+ if (!isEnumeration (t)) return false ;
359+ const std::string str = asString (t);
360+ return str == " T" || str == " F" ;
361+ }
362+ bool TokenFunc::isFloat (const Token& t) {
363+ if (isOperator (t)) return false ;
364+ const std::string str = asString (t);
365+ const char * start = str.c_str ();
366+ char * end;
367+ double result = strtod (start,&end);
368+ return ((end - start) == str.length ());
369+ }
349370int TokenFunc::asInt (const Token& t) {
350371 const std::string str = asString (t);
351372 // In case of an ENTITY_INSTANCE_NAME skip the leading #
@@ -415,6 +436,22 @@ ArgumentList::ArgumentList(Tokens* t, std::vector<unsigned int>& ids) {
415436 }
416437}
417438
439+ IfcUtil::ArgumentType ArgumentList::type () const {
440+ if (list.empty ()) return IfcUtil::Argument_UNKNOWN;
441+ const IfcUtil::ArgumentType elem_type = list[0 ]->type ();
442+ if (elem_type == IfcUtil::Argument_INT) {
443+ return IfcUtil::Argument_VECTOR_INT;
444+ } else if (elem_type == IfcUtil::Argument_DOUBLE) {
445+ return IfcUtil::Argument_VECTOR_DOUBLE;
446+ } else if (elem_type == IfcUtil::Argument_STRING) {
447+ return IfcUtil::Argument_VECTOR_STRING;
448+ } else if (elem_type == IfcUtil::Argument_ENTITY) {
449+ return IfcUtil::Argument_ENTITY_LIST;
450+ } else {
451+ return IfcUtil::Argument_UNKNOWN;
452+ }
453+ }
454+
418455void ArgumentList::Push (Argument* l) {
419456 list.push_back (l);
420457}
@@ -499,6 +536,24 @@ ArgumentList::~ArgumentList() {
499536 list.clear ();
500537}
501538
539+ IfcUtil::ArgumentType TokenArgument::type () const {
540+ if (TokenFunc::isInt (token)) {
541+ return IfcUtil::Argument_INT;
542+ } else if (TokenFunc::isBool (token)) {
543+ return IfcUtil::Argument_BOOL;
544+ } else if (TokenFunc::isFloat (token)) {
545+ return IfcUtil::Argument_DOUBLE;
546+ } else if (TokenFunc::isString (token)) {
547+ return IfcUtil::Argument_STRING;
548+ } else if (TokenFunc::isEnumeration (token)) {
549+ return IfcUtil::Argument_ENUMERATION;
550+ } else if (TokenFunc::isIdentifier (token)) {
551+ return IfcUtil::Argument_ENTITY;
552+ } else {
553+ return IfcUtil::Argument_UNKNOWN;
554+ }
555+ }
556+
502557//
503558// Functions for casting the TokenArgument to other types
504559//
@@ -522,6 +577,11 @@ std::string TokenArgument::toString(bool upper) const {
522577 }
523578}
524579bool TokenArgument::isNull () const { return TokenFunc::isOperator (token,' $' ); }
580+
581+ IfcUtil::ArgumentType EntityArgument::type () const {
582+ return IfcUtil::Argument_ENTITY;
583+ }
584+
525585//
526586// Functions for casting the EntityArgument to other types
527587//
@@ -679,8 +739,8 @@ IfcEntityList::ptr Entity::getInverse(IfcSchema::Type::Enum c, int i, const std:
679739bool Entity::is (IfcSchema::Type::Enum v) const { return _type == v; }
680740unsigned int Entity::id () { return _id; }
681741
682- bool Entity::isWritable () {
683- return false ;
742+ IfcWrite::IfcWritableEntity* Entity::isWritable () {
743+ return 0 ;
684744}
685745
686746IfcFile::IfcFile () {
@@ -822,7 +882,7 @@ void IfcFile::AddEntity(IfcUtil::IfcBaseClass* entity) {
822882 // For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set
823883 if ( entity->entity ->isWritable () ) {
824884 if ( ! entity->entity ->file ) entity->entity ->file = this ;
825- new_id = ((IfcWrite::IfcWritableEntity*)( entity->entity ) )->setId ();
885+ new_id = entity->entity -> isWritable ( )->setId ();
826886 } else {
827887 // TODO: Detect and fix ENTITY_INSTANCE_NAME collisions
828888 new_id = entity->entity ->id ();
@@ -837,22 +897,32 @@ void IfcFile::AddEntity(IfcUtil::IfcBaseClass* entity) {
837897 unsigned arg_count = entity->entity ->getArgumentCount ();
838898 for (unsigned i = 0 ; i < arg_count; ++i) {
839899 Argument* arg = entity->entity ->getArgument (i);
900+
901+ // Create a flat list of entity instances referenced by the instance that is being added
840902 IfcEntityList::ptr entity_attributes (new IfcEntityList);
841- try {
903+ if (arg-> type () == IfcUtil::Argument_ENTITY) {
842904 IfcUtil::IfcBaseClass* entity_attribute = *arg;
843905 entity_attributes->push (entity_attribute);
844- } catch (IfcParse::IfcException&) {
845- try {
846- IfcEntityList::ptr entity_list_attribute = *arg;
847- entity_attributes->push (entity_list_attribute);
848- } catch (IfcParse::IfcException&) {}
906+ } else if (arg->type () == IfcUtil::Argument_ENTITY_LIST) {
907+ IfcEntityList::ptr entity_list_attribute = *arg;
908+ entity_attributes->push (entity_list_attribute);
909+ } else if (arg->type () == IfcUtil::Argument_ENTITY_LIST_LIST) {
910+ IfcEntityListList::ptr entity_list_attribute = *arg;
911+ for (IfcEntityListList::outer_it it = entity_list_attribute->begin (); it != entity_list_attribute->end (); ++it) {
912+ for (IfcEntityListList::inner_it jt = it->begin (); jt != it->end (); ++jt) {
913+ entity_attributes->push (*jt);
914+ }
915+ }
849916 }
917+
850918 for (IfcEntityList::it it = entity_attributes->begin (); it != entity_attributes->end (); ++it) {
851919 IfcUtil::IfcBaseClass* entity_attribute = *it;
852920 try {
853921 if (entity_attribute->entity ->isWritable ()) {
854- if ( ! entity_attribute->entity ->file ) entity_attribute->entity ->file = this ;
855- ((IfcWrite::IfcWritableEntity*)(entity_attribute->entity ))->setId ();
922+ if ( ! entity_attribute->entity ->file ) {
923+ entity_attribute->entity ->file = this ;
924+ }
925+ entity_attribute->entity ->isWritable ()->setId ();
856926 }
857927 unsigned entity_attribute_id = entity_attribute->entity ->id ();
858928 IfcEntityList::ptr refs = EntitiesByReference (entity_attribute_id);
0 commit comments