libSplash
DCGroup.cpp
1 
26 #include <string>
27 #include <sstream>
28 #include <cassert>
29 #include <string.h>
30 #include <typeinfo>
31 
32 #include "splash/core/DCGroup.hpp"
33 #include "splash/basetypes/basetypes.hpp"
34 #include <splash/basetypes/generateCollectionType.hpp>
35 
36 #define H5_TRUE 1
37 #define H5_FALSE 0
38 
39 namespace splash
40 {
41 
42  std::string DCGroup::getExceptionString(std::string msg, std::string name)
43  {
44  return (std::string("Exception for DCGroup [") + name + std::string("] ") +
45  msg);
46  }
47 
48  DCGroup::DCGroup() :
49  checkExistence(true)
50  {
51  }
52 
53  DCGroup::~DCGroup()
54  {
55  close();
56  }
57 
58  H5Handle DCGroup::create(H5Handle base, std::string path)
59  throw (DCException)
60  {
61  bool mustCreate = false;
62  H5Handle currentHandle = base;
63  char c_path[path.size() + 1];
64  strcpy(c_path, path.c_str());
65 
66  char *token = strtok(c_path, "/");
67  while (token)
68  {
69  if (mustCreate || !H5Lexists(currentHandle, token, H5P_DEFAULT))
70  {
71  H5Handle newHandle = H5Gcreate(currentHandle, token, H5P_LINK_CREATE_DEFAULT,
72  H5P_GROUP_CREATE_DEFAULT, H5P_GROUP_ACCESS_DEFAULT);
73  if (newHandle < 0)
74  throw DCException(getExceptionString("Failed to create group", path));
75 
76  currentHandle = newHandle;
77  mustCreate = true;
78  } else
79  {
80  currentHandle = H5Gopen(currentHandle, token, H5P_DEFAULT);
81  if (currentHandle < 0)
82  {
83  if (checkExistence)
84  throw DCException(getExceptionString("Failed to create group", path));
85 
86  currentHandle = H5Gcreate(currentHandle, token, H5P_LINK_CREATE_DEFAULT,
87  H5P_GROUP_CREATE_DEFAULT, H5P_GROUP_ACCESS_DEFAULT);
88  if (currentHandle < 0)
89  throw DCException(getExceptionString("Failed to create group", path));
90 
91  mustCreate = true;
92  }
93  }
94 
95  handles.push_back(currentHandle);
96  token = strtok(NULL, "/");
97  }
98 
99  return currentHandle;
100  }
101 
102  H5Handle DCGroup::open(H5Handle base, std::string path)
103  throw (DCException)
104  {
105  H5Handle newHandle;
106  const bool is_basepath(path == std::string("/"));
107 
108  if (checkExistence && !H5Lexists(base, path.c_str(), H5P_DEFAULT) &&
109  !is_basepath)
110  throw DCException(getExceptionString("Failed to open group", path));
111 
112  newHandle = H5Gopen(base, path.c_str(), H5P_DEFAULT);
113 
114  if (newHandle < 0)
115  throw DCException(getExceptionString("Failed to open group", path));
116 
117  handles.push_back(newHandle);
118  return newHandle;
119  }
120 
121  H5Handle DCGroup::openCreate(H5Handle base, std::string path)
122  throw (DCException)
123  {
124  if (checkExistence && exists(base, path))
125  return open(base, path);
126  else
127  return create(base, path);
128  }
129 
130  void DCGroup::close()
131  throw (DCException)
132  {
133  for (HandlesList::const_reverse_iterator iter = handles.rbegin();
134  iter != handles.rend(); ++iter)
135  {
136  if (H5Gclose(*iter) < 0)
137  throw DCException(getExceptionString("Failed to close group", ""));
138  }
139 
140  handles.clear();
141  }
142 
143  bool DCGroup::exists(H5Handle base, std::string path)
144  {
145  return (H5Lexists(base, path.c_str(), H5P_DEFAULT) == H5_TRUE);
146  }
147 
148  void DCGroup::remove(H5Handle base, std::string path)
149  throw (DCException)
150  {
151  if (H5Ldelete(base, path.c_str(), H5P_LINK_ACCESS_DEFAULT) < 0)
152  throw DCException(getExceptionString("failed to remove group", path));
153  }
154 
155  H5Handle DCGroup::getHandle()
156  {
157  if (handles.size() > 0)
158  return *(handles.rbegin());
159  else
160  return INVALID_HANDLE;
161  }
162 
163  void DCGroup::getEntriesInternal(H5Handle base, const std::string baseGroup,
164  std::string baseName, VisitObjCBType *param)
165  throw (DCException)
166  {
167  H5G_info_t group_info;
168  H5Gget_info(base, &group_info);
169 
170  for (size_t i = 0; i < group_info.nlinks; ++i)
171  {
172  std::string currentBaseName = baseName;
173  std::string currentEntryName = "";
174 
175  H5O_info_t obj_info;
176  H5Oget_info_by_idx(base, ".", H5_INDEX_NAME, H5_ITER_INC, i, &obj_info, H5P_DEFAULT);
177 
178  if (param->entries)
179  {
180  ssize_t len_name = H5Lget_name_by_idx(base, ".", H5_INDEX_NAME,
181  H5_ITER_INC, i, NULL, 0, H5P_LINK_ACCESS_DEFAULT);
182  char *link_name_c = new char[len_name + 1];
183  H5Lget_name_by_idx(base, ".", H5_INDEX_NAME,
184  H5_ITER_INC, i, link_name_c, len_name + 1, H5P_LINK_ACCESS_DEFAULT);
185 
186  currentEntryName = std::string(link_name_c);
187  if (obj_info.type == H5O_TYPE_GROUP)
188  {
189  currentEntryName += std::string("/");
190  }
191  currentBaseName += currentEntryName;
192 
193  delete[] link_name_c;
194  }
195 
196  if (obj_info.type == H5O_TYPE_GROUP)
197  {
198  hid_t group_id = H5Oopen_by_idx(base, ".", H5_INDEX_NAME, H5_ITER_INC, i, H5P_DEFAULT);
199  getEntriesInternal(group_id, baseGroup, currentBaseName, param);
200  H5Oclose(group_id);
201  }
202 
203  if (obj_info.type == H5O_TYPE_DATASET)
204  {
205  if (param->entries)
206  {
207  param->entries[param->count].name = currentBaseName;
208 
209  hid_t dataset_id = H5Oopen_by_idx(base, ".", H5_INDEX_NAME, H5_ITER_INC, i, H5P_DEFAULT);
210  hid_t datatype_id = H5Dget_type(dataset_id);
211  param->entries[param->count].colType = generateCollectionType(datatype_id);
212  H5Dclose(datatype_id);
213  H5Oclose(dataset_id);
214  }
215 
216  param->count++;
217  }
218  }
219  }
220 }
CollectionType * generateCollectionType(hid_t datatype_id)