28 hid_t open_attribute(archive
const & ar, hid_t file_id, std::string path);
29 herr_t list_children_visitor(hid_t,
char const * n,
const H5L_info_t *,
void * d);
30 herr_t list_attributes_visitor(hid_t,
char const * n,
const H5A_info_t *,
void * d);
38 if (prop &
MEMORY) mode +=
"m";
40 prop = prop & ~(COMPRESS|
MEMORY);
44 }
else if (prop ==
WRITE) {
57 : current_(arg.current_)
58 , context_(arg.context_)
60 if (context_ != NULL) {
62 ++ref_cnt_[file_key(context_->filename_, context_->memory_)].second;
70 }
catch (std::exception & ex) {
71 std::cerr <<
"Error destructing archive of file '" << ex.what() << std::endl;
96 H5Fflush(context_->file_id_, H5F_SCOPE_GLOBAL);
97 if (!--ref_cnt_[file_key(context_->filename_, context_->memory_)].second) {
98 ref_cnt_.erase(file_key(context_->filename_, context_->memory_));
107 if (mode.find_first_not_of(
"rwacm")!=std::string::npos)
111 (mode.find_last_of(
'w') == std::string::npos ? 0 :
WRITE)
112 | (mode.find_last_of(
'a') == std::string::npos ? 0 :
WRITE)
113 | (mode.find_last_of(
'c') == std::string::npos ? 0 :
COMPRESS)
114 | (mode.find_last_of(
'm') == std::string::npos ? 0 :
MEMORY)
119 return context_ != NULL;
123 if (context_ == NULL)
125 return context_->filename_;
129 char chars[] = {
'&',
'/'};
130 for (std::size_t i = 0; i <
sizeof(chars); ++i)
131 for (std::size_t pos = segment.find_first_of(chars[i]); pos < std::string::npos; pos = segment.find_first_of(chars[i], pos + 1))
132 segment = segment.substr(0, pos) +
"&#" + cast<std::string>(
static_cast<int>(chars[i])) +
";" + segment.substr(pos + 1);
137 for (std::size_t pos = segment.find_first_of(
'&'); pos < std::string::npos; pos = segment.find_first_of(
'&', pos + 1))
138 segment = segment.substr(0, pos)
139 +
static_cast<char>(cast<int>(segment.substr(pos + 2, segment.find_first_of(
';', pos) - pos - 2)))
140 + segment.substr(segment.find_first_of(
';', pos) + 1);
154 if (path.size() > 1 && *path.rbegin() ==
'/')
155 path = path.substr(0, path.size() - 1);
156 if (path.size() && path[0] ==
'/')
158 else if (path.size() < 2 || path.substr(0, 2) !=
"..")
159 return current_ + (current_.size() == 1 || !path.size() ?
"" :
"/") + path;
161 std::string ctx = current_;
162 while (ctx.size() && path.size() && path.substr(0, 2) ==
"..") {
163 ctx = ctx.substr(0, ctx.find_last_of(
'/'));
164 path = path.size() == 2 ?
"" : path.substr(3);
166 return ctx + (ctx.size() == 1 || !path.size() ?
"" :
"/") + path;
171 if (context_ == NULL)
173 if ((path =
complete_path(path)).find_last_of(
'@') != std::string::npos)
176 hid_t
id = H5Dopen2(context_->file_id_, path.c_str(), H5P_DEFAULT);
177 return id < 0 ?
false : detail::check_data(
id) != 0;
181 if (context_ == NULL)
183 if ((path =
complete_path(path)).find_last_of(
'@') == std::string::npos)
186 return detail::check_error(H5Aexists_by_name(context_->file_id_, path.substr(0, path.find_last_of(
'@')).c_str(), path.substr(path.find_last_of(
'@') + 1).c_str(), H5P_DEFAULT));
190 if (context_ == NULL)
192 if ((path =
complete_path(path)).find_last_of(
'@') != std::string::npos)
195 hid_t
id = H5Gopen2(context_->file_id_, path.c_str(), H5P_DEFAULT);
196 return id < 0 ?
false : detail::check_group(
id) != 0;
201 if (context_ == NULL)
205 detail::attribute_type attr_id(detail::open_attribute(*
this, context_->file_id_, path));
206 space_id = H5Aget_space(attr_id);
207 }
else if (path.find_last_of(
'@') == std::string::npos &&
is_data(path)) {
208 detail::data_type data_id(H5Dopen2(context_->file_id_, path.c_str(), H5P_DEFAULT));
209 space_id = H5Dget_space(data_id);
211 #ifdef ALPS_HDF5_READ_GREEDY 216 H5S_class_t type = H5Sget_simple_extent_type(space_id);
217 detail::check_space(space_id);
218 if (type == H5S_NO_CLASS)
220 return type == H5S_SCALAR;
225 if (context_ == NULL)
228 if ((path =
complete_path(path)).find_last_of(
'@') != std::string::npos) {
229 detail::attribute_type attr_id(detail::open_attribute(*
this, context_->file_id_, path));
230 space_id = H5Aget_space(attr_id);
232 detail::data_type data_id(H5Dopen2(context_->file_id_, path.c_str(), H5P_DEFAULT));
233 space_id = H5Dget_space(data_id);
235 H5S_class_t type = H5Sget_simple_extent_type(space_id);
236 detail::check_space(space_id);
237 if (type == H5S_NO_CLASS)
239 return type == H5S_NULL;
243 if (context_ == NULL)
246 if ((path =
complete_path(path)).find_last_of(
'@') != std::string::npos)
247 return is_attribute(path.substr(0, path.find_last_of(
'@')) +
"@__complex__:" + path.substr(path.find_last_of(
'@') + 1))
248 &&
is_scalar(path.substr(0, path.find_last_of(
'@')) +
"@__complex__:" + path.substr(path.find_last_of(
'@') + 1));
251 for (std::size_t i = 0; i < children.size(); ++i)
260 if (context_ == NULL)
262 if ((path =
complete_path(path)).find_last_of(
'@') != std::string::npos)
264 std::vector<std::string> list;
268 detail::group_type group_id(H5Gopen2(context_->file_id_, path.c_str(), H5P_DEFAULT));
269 detail::check_error(H5Literate(group_id, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, detail::list_children_visitor, &list));
274 if (context_ == NULL)
276 if ((path =
complete_path(path)).find_last_of(
'@') != std::string::npos)
278 std::vector<std::string> list;
281 detail::group_type id(H5Gopen2(context_->file_id_, path.c_str(), H5P_DEFAULT));
282 detail::check_error(H5Aiterate2(
id, H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, NULL, detail::list_attributes_visitor, &list));
284 detail::data_type id(H5Dopen2(context_->file_id_, path.c_str(), H5P_DEFAULT));
285 detail::check_error(H5Aiterate2(
id, H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, NULL, detail::list_attributes_visitor, &list));
292 if (context_ == NULL)
295 return std::vector<std::size_t>(1, 0);
297 return std::vector<std::size_t>(1, 1);
298 std::vector<hsize_t> buffer(
dimensions(path), 0);
301 if (path.find_last_of(
'@') != std::string::npos) {
302 detail::attribute_type attr_id(detail::open_attribute(*
this, context_->file_id_, path));
303 space_id = H5Aget_space(attr_id);
305 detail::data_type data_id(H5Dopen2(context_->file_id_, path.c_str(), H5P_DEFAULT));
306 space_id = H5Dget_space(data_id);
308 detail::check_error(H5Sget_simple_extent_dims(space_id, &buffer.front(), NULL));
309 detail::check_space(space_id);
310 std::vector<std::size_t>
extent(buffer.begin(), buffer.end());
315 if (context_ == NULL)
318 if ((path =
complete_path(path)).find_last_of(
'@') != std::string::npos) {
319 detail::attribute_type attr_id(detail::open_attribute(*
this, context_->file_id_, path));
320 return detail::check_error(H5Sget_simple_extent_dims(detail::space_type(H5Aget_space(attr_id)), NULL, NULL));
322 detail::data_type data_id(H5Dopen2(context_->file_id_, path.c_str(), H5P_DEFAULT));
323 return detail::check_error(H5Sget_simple_extent_dims(detail::space_type(H5Dget_space(data_id)), NULL, NULL));
328 if (context_ == NULL)
330 if ((path =
complete_path(path)).find_last_of(
'@') != std::string::npos)
338 for (pos = path.find_last_of(
'/'); group_id < 0 && pos > 0 && pos < std::string::npos; pos = path.find_last_of(
'/', pos - 1))
339 group_id = H5Gopen2(context_->file_id_, path.substr(0, pos).c_str(), H5P_DEFAULT);
341 if ((pos = path.find_first_of(
'/', 1)) != std::string::npos) {
342 detail::property_type prop_id(H5Pcreate(H5P_GROUP_CREATE));
343 detail::check_error(H5Pset_link_creation_order(prop_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)));
344 detail::check_error(H5Pset_attr_creation_order(prop_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)));
345 detail::check_group(H5Gcreate2(context_->file_id_, path.substr(0, pos).c_str(), H5P_DEFAULT, prop_id, H5P_DEFAULT));
348 pos = path.find_first_of(
'/', pos + 1);
349 detail::check_group(group_id);
351 while (pos != std::string::npos && (pos = path.find_first_of(
'/', pos + 1)) != std::string::npos && pos > 0) {
352 detail::property_type prop_id(H5Pcreate(H5P_GROUP_CREATE));
353 detail::check_error(H5Pset_link_creation_order(prop_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)));
354 detail::check_error(H5Pset_attr_creation_order(prop_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)));
355 detail::check_group(H5Gcreate2(context_->file_id_, path.substr(0, pos).c_str(), H5P_DEFAULT, prop_id, H5P_DEFAULT));
357 detail::property_type prop_id(H5Pcreate(H5P_GROUP_CREATE));
358 detail::check_error(H5Pset_link_creation_order(prop_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)));
359 detail::check_error(H5Pset_attr_creation_order(prop_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)));
360 detail::check_group(H5Gcreate2(context_->file_id_, path.c_str(), H5P_DEFAULT, prop_id, H5P_DEFAULT));
365 if (context_ == NULL)
367 if ((path =
complete_path(path)).find_last_of(
'@') != std::string::npos)
371 detail::check_error(H5Ldelete(context_->file_id_, path.c_str(), H5P_DEFAULT));
377 if (context_ == NULL)
379 if ((path =
complete_path(path)).find_last_of(
'@') != std::string::npos)
383 detail::check_error(H5Ldelete(context_->file_id_, path.c_str(), H5P_DEFAULT));
389 if (context_ == NULL)
391 if ((path =
complete_path(path)).find_last_of(
'@') == std::string::npos)
398 if (context_ == NULL)
401 if (path.find_last_of(
'@') != std::string::npos)
402 write(path.substr(0, path.find_last_of(
'@')) +
"@__complex__:" + path.substr(path.find_last_of(
'@') + 1),
true);
406 for (std::vector<std::string>::const_iterator it = children.begin(); it != children.end(); ++it)
409 write(path +
"/@__complex__",
true);
414 return detail::archive_proxy<archive>(path, *
this);
417 void archive::construct(std::string
const & filename, std::size_t props) {
419 detail::check_error(H5Eset_auto2(H5E_DEFAULT, NULL, NULL));
422 detail::check_error(H5Zget_filter_info(H5Z_FILTER_SZIP, &flag));
423 props &= (flag & H5Z_FILTER_CONFIG_ENCODE_ENABLED ? ~0x00 : ~COMPRESS);
425 if (ref_cnt_.find(file_key(filename, props &
MEMORY)) == ref_cnt_.end())
426 ref_cnt_.insert(std::make_pair(
427 file_key(filename, props & MEMORY)
428 , std::make_pair(context_ =
new detail::archivecontext(filename, props &
WRITE,
false, props & COMPRESS, props & MEMORY), 1)
431 context_ = ref_cnt_.find(file_key(filename, props & MEMORY))->second.first;
432 context_->grant(props & WRITE,
false);
433 ++ref_cnt_.find(file_key(filename, props & MEMORY))->second.second;
437 std::string archive::file_key(std::string filename,
bool memory)
const {
438 return (memory ?
"m" :
"_") + filename;
441 #ifndef ALPS_SINGLE_THREAD 442 boost::recursive_mutex archive::mutex_;
444 std::map<std::string, std::pair<detail::archivecontext *, std::size_t> > archive::ref_cnt_;
448 #undef ALPS_HDF5_FOREACH_NATIVE_TYPE_INTEGRAL
std::size_t dimensions(std::string path) const
bool is_scalar(std::string path) const
detail::archive_proxy< archive > operator[](std::string const &path)
void open(const std::string &filename, const std::string &mode="r")
bool is_attribute(std::string path) const
bool is_data(std::string path) const
void delete_data(std::string path) const
void delete_group(std::string path) const
#define ALPS_HDF5_LOCK_MUTEX
std::vector< std::string > list_attributes(std::string path) const
void set_context(std::string const &context)
void delete_attribute(std::string path) const
std::vector< std::size_t > extent(std::string path) const
#define ALPS_HDF5_FAKE_THREADSAFETY
void create_group(std::string path) const
std::string get_context() const
bool is_null(std::string path) const
std::string encode_segment(std::string segment) const
std::vector< std::string > list_children(std::string path) const
auto write(std::string path, T const *value, std::vector< std::size_t > size, std::vector< std::size_t > chunk=std::vector< std::size_t >(), std::vector< std::size_t > offset=std::vector< std::size_t >()) const -> typename std::enable_if<!is_native_type< T >::value, void >::type
void set_complex(std::string path)
bool is_group(std::string path) const
std::string complete_path(std::string path) const
std::string decode_segment(std::string segment) const
std::string const & get_filename() const
bool is_complex(std::string path) const