7 #include "fwAtomsBoostIO/Reader.hpp" 9 #include "fwAtomsBoostIO/Writer.hpp" 11 #include <fwAtoms/Blob.hpp> 12 #include <fwAtoms/Boolean.hpp> 13 #include <fwAtoms/Map.hpp> 14 #include <fwAtoms/Numeric.hpp> 15 #include <fwAtoms/Numeric.hxx> 16 #include <fwAtoms/Object.hpp> 17 #include <fwAtoms/Sequence.hpp> 18 #include <fwAtoms/String.hpp> 20 #include <fwTools/UUID.hpp> 22 #include <fwZip/IReadArchive.hpp> 24 #include <boost/filesystem/operations.hpp> 25 #include <boost/property_tree/json_parser.hpp> 26 #include <boost/property_tree/xml_parser.hpp> 35 size_t countSubAtoms(const ::boost::property_tree::ptree& pt)
38 for(const ::boost::property_tree::ptree::value_type& v : pt)
41 (v.first ==
"numeric") ||
42 (v.first ==
"string") ||
43 (v.first ==
"boolean") ||
44 (v.first ==
"sequence") ||
46 (v.first ==
"object") ||
52 nb += countSubAtoms(v.second);
62 typedef std::map< std::string, ::fwAtoms::Base::sptr > AtomCacheType;
64 AtomCacheType m_cache;
65 const ::boost::property_tree::ptree& m_root;
66 ::fwZip::IReadArchive::sptr m_archive;
70 PTreeVisitor(const ::boost::property_tree::ptree& pt, const ::fwZip::IReadArchive::sptr& archive) :
78 AtomCacheType::mapped_type hitCache(
const AtomCacheType::key_type& path)
const 80 AtomCacheType::const_iterator iter = m_cache.find(path);
81 if(iter != m_cache.end())
85 return AtomCacheType::mapped_type();
90 void cache(
const std::string& ptpath,
const AtomCacheType::mapped_type& atom)
92 m_cache.insert( AtomCacheType::value_type( ptpath, atom ) );
97 ::fwAtoms::Boolean::sptr getBoolean(const ::boost::property_tree::ptree& pt,
const std::string& ptpath)
100 this->cache(ptpath, atom);
106 ::fwAtoms::Numeric::sptr getNumeric(const ::boost::property_tree::ptree& pt,
const std::string& ptpath )
109 this->cache(ptpath, atom);
115 ::fwAtoms::String::sptr getString(const ::boost::property_tree::ptree& pt,
const std::string& ptpath )
118 this->cache(ptpath, atom);
124 ::fwAtoms::Sequence::sptr getSequence(const ::boost::property_tree::ptree& pt,
const std::string& ptpath )
126 ::fwAtoms::Sequence::sptr atom = ::fwAtoms::Sequence::New();
127 this->cache(ptpath, atom);
131 std::vector<const ::boost::property_tree::ptree::value_type*> elems;
132 std::for_each(pt.get_child(
"sequence").begin(), pt.get_child(
"sequence").end(),
133 [&](::boost::property_tree::ptree::value_type
const& elem)
135 elems.push_back(&elem);
137 std::sort(elems.begin(), elems.end(),
138 [&](const ::boost::property_tree::ptree::value_type* s1,
139 const ::boost::property_tree::ptree::value_type* s2)
141 const unsigned long n1 = std::stoul(s1->first),
142 n2 = std::stoul(s2->first);
147 for( const ::boost::property_tree::ptree::value_type* val : elems )
149 std::string subPath = ptpath + (ptpath.empty() ?
"" :
".") +
"sequence." + val->first;
150 ::fwAtoms::Base::sptr subAtom = this->visit(val->second, subPath );
151 atom->push_back( subAtom );
158 ::fwAtoms::Map::sptr getMap(const ::boost::property_tree::ptree& pt,
const std::string& ptpath )
160 ::fwAtoms::Map::sptr atom = ::fwAtoms::Map::New();
161 this->cache(ptpath, atom);
163 for( const ::boost::property_tree::ptree::value_type& val : pt.get_child(
"map") )
165 std::string subPath = ptpath + (ptpath.empty() ?
"" :
".") +
"map." + val.first +
".value";
167 ::boost::property_tree::ptree mapChild = val.second;
168 ::boost::property_tree::ptree value = mapChild.get_child(
"value");
170 ::fwAtoms::Base::sptr subAtom = this->visit( value, subPath );
172 std::string key = mapChild.get<std::string>(
"key");
173 atom->insert( key, subAtom );
180 ::fwAtoms::Object::sptr getObject(const ::boost::property_tree::ptree& pt,
const std::string& ptpath )
182 using ::boost::property_tree::ptree;
183 ::fwAtoms::Object::sptr atom = ::fwAtoms::Object::New();
184 this->cache(ptpath, atom);
186 const ptree& metaInfosTree = pt.get_child(
"object.meta_infos");
187 const ptree& attributesTree = pt.get_child(
"object.attributes");
189 ::fwAtoms::Object::MetaInfosType metaInfos;
190 for(
const ptree::value_type& val : metaInfosTree )
192 ::boost::property_tree::ptree item = val.second;
194 ::fwAtoms::Object::MetaInfosType::value_type value(
195 item.get<std::string>(
"key"), item.get<std::string>(
"value") );
196 metaInfos.insert( value );
198 atom->setMetaInfos(metaInfos);
200 ::fwAtoms::Object::AttributesType attributes;
201 for(
const ptree::value_type& val : attributesTree )
203 std::string subPath = ptpath + (ptpath.empty() ?
"" :
".")+
"object.attributes." + val.first;
204 ::fwAtoms::Base::sptr subAtom = this->visit(val.second, subPath );
205 ::fwAtoms::Object::AttributesType::value_type value(val.first, subAtom);
206 attributes.insert( value );
208 atom->setAttributes(attributes);
211 if(atom->getMetaInfo(
"ID_METAINFO").empty())
232 SPTR(std::istream)
get()
234 return m_archive->getFile(m_path);
237 ::fwZip::IReadArchive::sptr m_archive;
238 ::boost::filesystem::path m_path;
243 ::fwAtoms::Blob::sptr getBlob(const ::boost::property_tree::ptree& pt,
const std::string& ptpath)
246 ::fwMemory::BufferObject::sptr buffObj = ::fwMemory::BufferObject::New();
247 atom->setBufferObject(buffObj);
249 this->cache(ptpath, atom);
251 const std::string bufType = pt.get<std::string>(
"blob.buffer_type");
255 size_t buffSize = pt.get<
size_t>(
"blob.buffer_size");
258 const ::boost::filesystem::path bufFile = pt.get<std::string>(
"blob.buffer");
259 ::boost::filesystem::path sourceFile =
"";
260 ::fwMemory::FileFormatType format = ::fwMemory::OTHER;
262 if( ::boost::filesystem::is_directory(m_archive->getArchivePath()))
264 sourceFile = m_archive->getArchivePath() / bufFile;
265 format = ::fwMemory::RAW;
268 buffObj->setIStreamFactory( std::make_shared< AtomsBoostIOReadStream >(m_archive->clone(), bufFile),
269 buffSize, sourceFile, format);
274 FW_RAISE(
"Buffer type '" << bufType <<
"' unknown.");
281 ::fwAtoms::Base::sptr visit(const ::boost::property_tree::ptree& pt, std::string ptpath =
"")
285 return ::fwAtoms::Base::sptr();
288 ::fwAtoms::Base::sptr atom = this->hitCache(ptpath);
295 if(pt.count(
"numeric") == 1 )
297 atom = this->getNumeric( pt, ptpath );
299 else if(pt.count(
"string") == 1)
301 atom = this->getString( pt, ptpath );
303 else if(pt.count(
"boolean") == 1)
305 atom = this->getBoolean( pt, ptpath );
307 else if(pt.count(
"sequence") == 1)
309 atom = this->getSequence( pt, ptpath );
311 else if(pt.count(
"map") == 1)
313 atom = this->getMap( pt, ptpath );
315 else if(pt.count(
"object") == 1)
317 atom = this->getObject( pt, ptpath );
319 else if(pt.count(
"blob") == 1)
321 atom = this->getBlob( pt, ptpath );
323 else if(pt.count(
"ref") == 1)
325 std::string ref = pt.get<std::string>(
"ref");
326 const ::boost::property_tree::ptree& refPt = m_root.get_child(ref);
327 atom = this->visit( refPt, ref );
331 FW_RAISE(
"Unknown element found in archive.");
339 ::fwAtoms::Base::sptr visit()
341 return this->visit(m_root);
348 ::fwAtoms::Base::sptr Reader::read( const ::fwZip::IReadArchive::sptr& archive,
349 const ::boost::filesystem::path& rootFilename,
350 FormatType format )
const 352 ::boost::property_tree::ptree root;
353 ::fwAtoms::Base::sptr atom;
355 SPTR(std::istream) in = archive->getFile(rootFilename);
358 ::boost::property_tree::json_parser::read_json(*in, root);
360 else if(format == XML)
362 ::boost::property_tree::xml_parser::read_xml(*in, root);
366 FW_RAISE(
"This kind of extension is not supported");
369 typedef ::boost::property_tree::ptree::const_assoc_iterator PtreeItType;
370 PtreeItType hasVersionsIt = root.find(
"versions");
371 FW_RAISE_IF(
"Failed to read file '" << rootFilename.string() <<
"':\nno versions found in specified file.",
372 hasVersionsIt == root.not_found());
374 ::boost::property_tree::ptree versions = root.get_child(
"versions");
377 FW_RAISE_IF(
"Failed to read file '" << rootFilename.string() <<
"':\nno atoms version found in specified file.",
378 hasAtomsVersionsIt == versions.not_found());
381 FW_RAISE_IF(
"Failed to read file '" << rootFilename.string() <<
"':\nno writer version found in specified file",
382 hasWriterVersionsIt == versions.not_found());
388 "Failed to read file '" << rootFilename.string() <<
"':\n" 389 <<
"Detected file version is '" << writerVersion <<
"'" 391 Writer::s_VERSION != writerVersion);
393 FW_RAISE_IF(
"Failed to read file '" << rootFilename.string() <<
"':\n" 394 <<
"Detected atoms version is '" << atomsVersion <<
"'" 396 ::fwAtoms::Base::s_VERSION != atomsVersion);
399 atom = visitor.visit();
The namespace fwAtomsBoostIO contains atom reader and writer.
static FWATOMS_API String::sptr New(std::string value)
Construct a new Object represented a string.
static FWATOMSBOOSTIO_API const std::string s_ATOMS_VERSION_KEY
Defines key to retrieve fwAtoms version from file.
static FWATOMSBOOSTIO_API const std::string s_WRITER_VERSION_KEY
Defines key to retrieve writer version from file.
static Numeric::sptr New(T value)
Build a new numeric type.
static FWATOMSBOOSTIO_API const std::string s_VERSION
Defines writer version.
static FWATOMS_API const std::string s_VERSION
Defines fwAtoms version.
static FWATOMS_API Boolean::sptr New(std::string value)
Construct an object storing a bool value.
static FWATOMS_API Blob::sptr New(::fwMemory::BufferObject::sptr buffer)
create a new Blob shared ptr.