Commit 83c0c239 authored by T.J. Corona's avatar T.J. Corona

Fix extensible file system io & add a test.

parent cd344b64
......@@ -224,14 +224,66 @@ smtk::common::UUID XmlDocV2Parser::getAttributeID(xml_node &attNode)
void XmlDocV2Parser::processFileItem(pugi::xml_node &node,
attribute::FileItemPtr item)
{
// still process FileItem as V1Parser, but add the recentValues after
this->XmlDocV1Parser::processFileItem(node, item);
std::size_t i=0, n = item->numberOfValues();
std::size_t numRequiredVals = item->numberOfRequiredValues();
xml_attribute xatt;
xml_node valsNode;
xml_node val;
if (item->isExtensible())
{
// The node should have an attribute indicating how many values are
// associated with the item
xatt = node.attribute("NumberOfValues");
if (!xatt)
{
smtkErrorMacro(this->m_logger,
"XML Attribute NumberOfValues is missing for Item: "
<< item->name());
return;
}
n = xatt.as_uint();
item->setNumberOfValues(n);
}
xml_node valsNode = node.child("RecentValues");
if (!n)
{
return;
}
valsNode = node.child("Values");
if (valsNode)
{
for (val = valsNode.child("Val"); val; val = val.next_sibling("Val"))
{
xatt = val.attribute("Ith");
if (!xatt)
{
smtkErrorMacro(this->m_logger,
"XML Attribute Ith is missing for Item: " << item->name());
continue;
}
i = xatt.as_uint();
if (i >= n)
{
smtkErrorMacro(this->m_logger, "XML Attribute Ith = " << i
<< " is out of range for Item: " << item->name());
continue;
}
item->setValue(static_cast<int>(i), val.text().get());
}
}
else if (numRequiredVals == 1)
{
item->setValue(node.text().get());
}
else
{
smtkErrorMacro(this->m_logger, "XML Node Values is missing for Item: " << item->name());
}
valsNode = node.child("RecentValues");
if (valsNode)
{
xml_node val;
for (val = valsNode.child("Val"); val; val = val.next_sibling("Val"))
{
item->addRecentValue(val.text().get());
......@@ -239,6 +291,67 @@ void XmlDocV2Parser::processFileItem(pugi::xml_node &node,
}
}
//----------------------------------------------------------------------------
void XmlDocV2Parser::processDirectoryItem(pugi::xml_node &node,
attribute::DirectoryItemPtr item)
{
std::size_t i=0, n = item->numberOfValues();
std::size_t numRequiredVals = item->numberOfRequiredValues();
xml_attribute xatt;
xml_node valsNode;
xml_node val;
if (item->isExtensible())
{
// The node should have an attribute indicating how many values are
// associated with the item
xatt = node.attribute("NumberOfValues");
if (!xatt)
{
smtkErrorMacro(this->m_logger,
"XML Attribute NumberOfValues is missing for Item: "
<< item->name());
return;
}
n = xatt.as_uint();
item->setNumberOfValues(n);
}
if (!n)
{
return;
}
valsNode = node.child("Values");
if (valsNode)
{
for (val = valsNode.child("Val"); val; val = val.next_sibling("Val"))
{
xatt = val.attribute("Ith");
if (!xatt)
{
smtkErrorMacro(this->m_logger,
"XML Attribute Ith is missing for Item: " << item->name());
continue;
}
i = xatt.as_uint();
if (i >= n)
{
smtkErrorMacro(this->m_logger, "XML Attribute Ith = " << i
<< " is out of range for Item: " << item->name());
continue;
}
item->setValue(static_cast<int>(i), val.text().get());
}
}
else if (numRequiredVals == 1)
{
item->setValue(node.text().get());
}
else
{
smtkErrorMacro(this->m_logger, "XML Node Values is missing for Item: " << item->name());
}
}
//----------------------------------------------------------------------------
void XmlDocV2Parser::processModelEntityItem(pugi::xml_node &node,
attribute::ModelEntityItemPtr item)
......@@ -400,7 +513,7 @@ void XmlDocV2Parser::processMeshEntityItem(pugi::xml_node &node,
<< " is out of range for Item: " << item->name());
break;
}
cid = smtk::common::UUID(xatt.value());
cid = smtk::common::UUID(xatt.value());
//convert back to a handle
cJSON* jshandle = cJSON_Parse(val.text().get());
......@@ -414,7 +527,7 @@ void XmlDocV2Parser::processMeshEntityItem(pugi::xml_node &node,
continue;
}
smtk::mesh::InterfacePtr interface =c->interface();
if(!interface)
{
std::cerr << "Expecting a valid mesh interface for mesh item: "
......@@ -520,7 +633,7 @@ void XmlDocV2Parser::processViews(xml_node &root)
"Could not find View's Title - skipping it!");
continue;
}
xatt = child.attribute("Type");
if (xatt)
{
......@@ -552,7 +665,7 @@ void XmlDocV2Parser::processViewComponent(smtk::common::View::Component &comp,
// Add the attributes of the node to the component
xml_attribute xatt;
std::string name;
for (xatt = node.first_attribute(); xatt; xatt = xatt.next_attribute())
{
// If this is the top View comp then skip Title and Type Attributes
......
......@@ -37,6 +37,8 @@ namespace smtk
protected:
virtual void processDefinition(pugi::xml_node &defNode,
smtk::attribute::DefinitionPtr def);
virtual void processDirectoryItem(pugi::xml_node &node,
smtk::attribute::DirectoryItemPtr item);
virtual void processDirectoryDef(pugi::xml_node &node,
smtk::attribute::DirectoryItemDefinitionPtr idef);
virtual void processFileItem(pugi::xml_node &node,
......@@ -59,7 +61,7 @@ namespace smtk
virtual void processViews(pugi::xml_node &root);
virtual void processViewComponent(smtk::common::View::Component &comp,
pugi::xml_node &node, bool isTopComp);
virtual smtk::common::UUID getAttributeID(pugi::xml_node &attNode);
private:
......
......@@ -1355,12 +1355,12 @@ void XmlV2StringWriter::processFileSystemItem(
// If the item can have variable number of values then store how many
// values it has
if (!numRequiredVals)
if (item->isExtensible())
{
node.append_attribute("NumberOfValues").set_value(static_cast<unsigned int>(n));
}
if (numRequiredVals == 1) // Special Common Case
if (numRequiredVals == 1 && !item->isExtensible()) // Special Common Case
{
if (item->isSet())
{
......@@ -1437,7 +1437,7 @@ void XmlV2StringWriter::processViews()
// First write toplevel views and then write out the non-toplevel - note that the
// attribute or view system do care about this - the assumption is that the designer would
// probably like all the toplevel views clustered together
xml_node views = this->m_pugi->root.append_child("Views");
std::map<std::string, smtk::common::ViewPtr>::const_iterator iter;
bool isTop;
......@@ -1449,7 +1449,7 @@ void XmlV2StringWriter::processViews()
}
xml_node node;
node = views.append_child("View");
node.append_attribute("Type").set_value(iter->second->type().c_str());
node.append_attribute("Title").set_value(iter->second->title().c_str());
if (iter->second->iconName() != "")
......@@ -1466,7 +1466,7 @@ void XmlV2StringWriter::processViews()
}
xml_node node;
node = views.append_child("View");
node.append_attribute("Type").set_value(iter->second->type().c_str());
node.append_attribute("Title").set_value(iter->second->title().c_str());
if (iter->second->iconName() != "")
......
set(ioTests
extensibleAttributeIOTest
loggerTest
ResourceSetTest
unitImportExportJSON
......@@ -6,8 +7,9 @@ set(ioTests
foreach (test ${ioTests})
add_executable(${test} ${test}.cxx)
target_link_libraries(${test} smtkCore smtkCoreModelTesting)
target_link_libraries(${test} smtkCore smtkCoreModelTesting ${Boost_LIBRARIES})
add_test(NAME ${test} COMMAND ${test})
target_compile_definitions(${test} PRIVATE "SMTK_SCRATCH_DIR=\"${CMAKE_BINARY_DIR}/Testing/Temporary\"")
endforeach()
......
//=========================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//=========================================================================
#include <iostream>
#include <sstream>
#include "smtk/attribute/Attribute.h"
#include "smtk/attribute/Definition.h"
#include "smtk/attribute/FileItem.h"
#include "smtk/attribute/StringItem.h"
#include "smtk/attribute/System.h"
#include "smtk/common/UUID.h"
#include "smtk/io/AttributeReader.h"
#include "smtk/io/AttributeWriter.h"
#include "smtk/io/Logger.h"
//force to use filesystem version 3
#define BOOST_FILESYSTEM_VERSION 3
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
namespace
{
std::string write_root = SMTK_SCRATCH_DIR;
void cleanup( const std::string& file_path )
{
//first verify the file exists
::boost::filesystem::path path( file_path );
if( ::boost::filesystem::is_regular_file( path ) )
{
//remove the file_path if it exists.
::boost::filesystem::remove( path );
}
}
const char* testInput =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?> "
"<SMTK_AttributeSystem Version=\"2\"> "
" <Definitions> "
" <AttDef Type=\"att1\" BaseType=\"\"> "
" <ItemDefinitions> "
" <String Name=\"myStrings\" Extensible=\"1\" "
" NumberOfRequiredValues=\"1\"> "
" </String> "
" <File Name=\"myFiles\" Extensible=\"1\" ShouldExist=\"false\" "
" NumberOfRequiredValues=\"1\"> "
" </File> "
" </ItemDefinitions> "
" </AttDef> "
" </Definitions> "
" <Attributes> "
" <Att Name=\"att\" Type=\"att1\"/> "
" </Attributes> "
"</SMTK_AttributeSystem> "
;
}
int main()
{
smtk::attribute::System system;
smtk::io::Logger logger;
smtk::io::AttributeReader reader;
if (reader.readContents(system, testInput, logger))
{
std::cerr << "Encountered Errors while reading input data\n";
std::cerr << logger.convertToString();
return -2;
}
std::vector<smtk::attribute::AttributePtr> atts;
system.attributes(atts);
if (atts.size() != 1)
{
std::cerr << "Unexpected number of attributes: "<<atts.size()<<"\n";
std::cerr << logger.convertToString();
return -2;
}
smtk::attribute::AttributePtr att = atts[0];
smtk::attribute::StringItemPtr myStrings = att->findString("myStrings");
myStrings->setNumberOfValues(2);
myStrings->setValue(0, "string0");
myStrings->setValue(1, "string1");
smtk::attribute::FileItemPtr myFiles = att->findFile("myFiles");
myFiles->setNumberOfValues(2);
myFiles->setValue(0, "/path/to/file0");
myFiles->setValue(1, "/path/to/file1");
if (!att->isValid())
{
std::cerr << "Input attributes are invalid\n";
std::cerr << logger.convertToString();
return -2;
}
std::stringstream s;
s << write_root << "/" << smtk::common::UUID::random().toString() << ".xml";
std::string fileName = s.str();
smtk::io::AttributeWriter writer;
if (writer.write(system, fileName, logger))
{
std::cerr << "Failed to write to " << fileName << "\n";
std::cerr << logger.convertToString();
return -2;
}
smtk::attribute::System copiedSystem;
if (reader.read(copiedSystem, fileName, logger))
{
std::cerr << "Failed to read from " << fileName << "\n";
std::cerr << logger.convertToString();
return -2;
}
{
std::vector<smtk::attribute::AttributePtr> copiedAtts;
copiedSystem.attributes(copiedAtts);
if (copiedAtts.size() != 1)
{
std::cerr << "Unexpected number of attributes: "<<copiedAtts.size()<<"\n";
std::cerr << logger.convertToString();
return -2;
}
smtk::attribute::AttributePtr copiedAtt = copiedAtts[0];
if (!copiedAtt->isValid())
{
std::cerr << "Copied attributes are invalid\n";
std::cerr << logger.convertToString();
return -2;
}
smtk::attribute::StringItemPtr myCopiedStrings =
copiedAtt->findString("myStrings");
smtk::attribute::ItemPtr myStringsAsItems =
std::static_pointer_cast<smtk::attribute::Item>(myStrings);
smtk::attribute::ConstItemPtr myStringsAsConstItems =
std::const_pointer_cast<smtk::attribute::Item>(myStringsAsItems);
myCopiedStrings->assign(myStringsAsConstItems);
if (myCopiedStrings->numberOfValues() != myStrings->numberOfValues())
{
std::cerr << "Unexpected number of string values: "<<myCopiedStrings->numberOfValues()<<" vs "<<myStrings->numberOfValues()<<"\n";
std::cerr << logger.convertToString();
return -2;
}
smtk::attribute::FileItemPtr myCopiedFiles = copiedAtt->findFile("myFiles");
smtk::attribute::ItemPtr myFilesAsItems =
std::static_pointer_cast<smtk::attribute::Item>(myFiles);
smtk::attribute::ConstItemPtr myFilesAsConstItems =
std::const_pointer_cast<smtk::attribute::Item>(myFilesAsItems);
myCopiedFiles->assign(myFilesAsConstItems);
if (myCopiedFiles->numberOfValues() != myFiles->numberOfValues())
{
std::cerr << "Unexpected number of file values: "<<myCopiedFiles->numberOfValues()<<" vs "<<myFiles->numberOfValues()<<"\n";
std::cerr << logger.convertToString();
return -2;
}
}
cleanup(fileName);
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment