// extensible object test, BuildingSurface:Detailed void IddFile_BuildingSurfaceDetailed(const IddFile& iddFile) { string objectName("BuildingSurface:Detailed"); OptionalIddObject object = iddFile.getObject(objectName); ASSERT_TRUE(object); EXPECT_TRUE(iequals(object->name(), objectName)); ASSERT_TRUE(object->nonextensibleFields().size() > 0); EXPECT_EQ(object->nonextensibleFields().size(), static_cast<unsigned int>(10)); EXPECT_FALSE(object->properties().format.empty()); EXPECT_TRUE(iequals("vertices", object->properties().format)); EXPECT_TRUE(object->properties().extensible); EXPECT_TRUE(object->properties().numExtensible); ASSERT_EQ(static_cast<unsigned int>(3), object->properties().numExtensible); EXPECT_FALSE(object->getField("Vertex 1 X-coordinate")); EXPECT_FALSE(object->getField("Vertex 1 X-coordinate")); ASSERT_TRUE(object->extensibleGroup().size() > 0); string fieldName("Vertex X-coordinate"); EXPECT_TRUE(iequals(fieldName, object->extensibleGroup().front().name() )); OptionalIddField field = object->getField(fieldName); ASSERT_TRUE(field); EXPECT_TRUE(iequals(fieldName, field->name())); EXPECT_TRUE(field->properties().beginExtensible); fieldName = "Vertex Z-coordinate"; EXPECT_TRUE(iequals(fieldName, object->extensibleGroup().back().name() )); field = object->getField(fieldName); ASSERT_TRUE(field); EXPECT_TRUE(iequals(fieldName, field->name())); EXPECT_FALSE(field->properties().beginExtensible); }
// case insensitive test void IddFile_bUiLdInG(const IddFile& iddFile) { string objectName("bUiLdInG"); OptionalIddObject object = iddFile.getObject(objectName); ASSERT_TRUE(object); EXPECT_TRUE(iequals(object->name(), objectName)); EXPECT_EQ(static_cast<unsigned int>(8),object->nonextensibleFields().size()); EXPECT_TRUE(object->properties().unique); EXPECT_TRUE(object->properties().required); string fieldName("TeRrAiN"); OptionalIddField field = object->getField(fieldName); ASSERT_TRUE(field); EXPECT_TRUE(iequals(field->name(), fieldName)); EXPECT_EQ(field->keys().size(), static_cast<unsigned int>(5) ); EXPECT_TRUE(field->properties().stringDefault); EXPECT_EQ(*(field->properties().stringDefault), "Suburbs"); EXPECT_FALSE(field->properties().numericDefault); string keyName("SuBuRbS"); OptionalIddKey key = field->getKey(keyName); ASSERT_TRUE(key); EXPECT_FALSE(equals(key->name(), keyName)); EXPECT_TRUE(iequals(key->name(), keyName)); }
// test single object, no fields void IddFile_LeadInput(const IddFile& iddFile) { string objectName("Lead Input"); OptionalIddObject object = iddFile.getObject(objectName); ASSERT_TRUE(object); EXPECT_EQ(object->name(), objectName); EXPECT_TRUE(object->nonextensibleFields().empty() ); }
// test single object, one alpha field, no keys void IddFile_Version(const IddFile& iddFile) { string objectName("Version"); OptionalIddObject object = iddFile.getObject(objectName); ASSERT_TRUE(object); EXPECT_EQ(object->name(), objectName); EXPECT_EQ(static_cast<unsigned int>(1),object->nonextensibleFields().size()); string fieldName("Version Identifier"); OptionalIddField field = object->getField(fieldName); ASSERT_TRUE(field); EXPECT_EQ(field->name(), fieldName); EXPECT_TRUE(field->keys().empty()); }
bool ImfFile::m_load(std::istream& is) { // keep track of line number in the Idf int lineNum = 0; // number of object in the Idf, 1 is first object int objectNum = 0; // temp string to read file std::string line; // this will contain matches to regular expressions boost::smatch matches; // keep running comment std::string comment; // keep track of the current section std::string section = ""; // get CommentOnly IddObject OptionalIddObject commentOnlyIddObject; commentOnlyIddObject = IddFactory::instance().getObject(IddObjectType::CommentOnly); OS_ASSERT(commentOnlyIddObject); // Use a boost filter to make sure that no matter what line endings come in, // they are converted to what is expected by the current os boost::iostreams::filtering_istream filt; //#ifdef _POSIX_VERSION filt.push(boost::iostreams::newline_filter(boost::iostreams::newline::posix)); //#else // filt.push(boost::iostreams::newline_filter(boost::iostreams::newline::dos)); //#endif filt.push(is); // read the rest of the file line by line // todo, do this by regex while (getline(filt, line)) { ++lineNum; if (boost::regex_match(line, idfRegex::commentOnlyLine())){ // continue comment comment += (line + idfRegex::newLinestring()); continue; } else if (boost::regex_match(line, commentRegex::whitespaceOnlyLine())){ // end comment boost::trim(comment); if (!comment.empty()){ // make a comment only object to hold the comment OptionalIdfObject commentOnlyObject; commentOnlyObject = IdfObject::load(commentOnlyIddObject->name() + ";" + comment, *commentOnlyIddObject); OS_ASSERT(commentOnlyObject); // put it in the object list m_sectionMap[section].push_back(*commentOnlyObject); } //clear out comment comment = ""; continue; } else if (boost::regex_search(line, matches, idfRegex::imfSection())){ // end comment boost::trim(comment); if (!comment.empty()){ // make a comment only object to hold the comment OptionalIddObject commentOnlyIddObject = IddFactory::instance().getObject(IddObjectType::CommentOnly); OS_ASSERT(commentOnlyIddObject); OptionalIdfObject commentOnlyObject; commentOnlyObject = IdfObject::load(commentOnlyIddObject->name() + ";" + comment, *commentOnlyIddObject); OS_ASSERT(commentOnlyObject); // put it in the object list m_sectionMap[section].push_back(*commentOnlyObject); } //clear out comment comment = ""; // get the new imf section section = std::string(matches[1].first, matches[1].second); boost::trim(section); } else if (boost::regex_search(line, matches, idfRegex::imfSectionEnd())) { // end comment boost::trim(comment); if (!comment.empty()){ // make a comment only object to hold the comment OptionalIdfObject commentOnlyObject; commentOnlyObject = IdfObject::load(commentOnlyIddObject->name() + ";" + comment, *commentOnlyIddObject); OS_ASSERT(commentOnlyObject); // put it in the object list m_sectionMap[section].push_back(*commentOnlyObject); } //clear out comment comment = ""; } else { // IdfObject bool foundEndLine(false); // a valid Idf object to parse ++objectNum; // peek at the object type and name for indexing in map std::string objectType; std::string objectName; //bool objectHasName(false); if (boost::regex_search(line, matches, idfRegex::objectTypeAndName())){ objectType = std::string(matches[1].first, matches[1].second); boost::trim(objectType); objectName = std::string(matches[2].first, matches[2].second); boost::trim(objectType); } else if (boost::regex_search(line, matches, idfRegex::line())){ // doesn't match name, just type objectType = std::string(matches[1].first, matches[1].second); boost::trim(objectType); } else{ // can't figure out the object's type LOG(Warn, "Unrecognizable object type '" + line + "'. Defaulting to 'Catchall'."); objectType = "Catchall"; } // get the corresponding idd object entry OptionalIddObject iddObject = m_iddFileAndFactoryWrapper.getObject(objectType); if (!iddObject){ LOG(Warn, "Cannot find object type '" + objectType + "' in Idd. Placing data in Catchall object."); iddObject = IddObject(); objectType = "Catchall"; } // put the text for this object in a new string with a newline std::string text(line + idfRegex::newLinestring()); // check if this line also matches closing line object if (boost::regex_match(line, idfRegex::objectEnd())){ foundEndLine = true; } // continue reading until we have seen the entire object // last line will be thrown away, requires empty line between objects in Idf while((!foundEndLine) && (std::getline(filt, line))){ ++lineNum; // add line to text, include newline separator text += (line + idfRegex::newLinestring()); // check if we have found the last field if (boost::regex_match(line, idfRegex::objectEnd())){ foundEndLine = true; } } // construct the object OptionalIdfObject object = IdfObject::load(text,*iddObject); if (!object) { LOG(Error,"Unable to construct IdfObject from text: " << std::endl << text << std::endl << "Throwing this object out and parsing the remainder of the file."); continue; } // put it in the object list m_sectionMap[section].push_back(*object); } } return true; }