1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4 *
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
6 *
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
13 *
14 */
15
16 #include "H5Group.hxx"
17 #include "H5File.hxx"
18 #include "H5SoftLinksList.hxx"
19 #include "H5GroupsList.hxx"
20 #include "H5DatasetsList.hxx"
21 #include "H5TypesList.hxx"
22 #include "H5Link.hxx"
23 #include "H5BasicData.hxx"
24
25 namespace org_modules_hdf5
26 {
27
init()28 void H5Group::init()
29 {
30 group = H5Gopen(getParent().getH5Id(), name.c_str(), H5P_DEFAULT);
31 if (group < 0)
32 {
33 throw H5Exception(__LINE__, __FILE__, _("Cannot open the group %s."), name.c_str());
34 }
35 }
36
H5Group(H5Object & _parent,const std::string & _name)37 H5Group::H5Group(H5Object & _parent, const std::string & _name) : H5Object(_parent, _name)
38 {
39 init();
40 }
41
H5Group(H5Object & _parent,hid_t _group,const std::string & _name)42 H5Group::H5Group(H5Object & _parent, hid_t _group, const std::string & _name) : H5Object(_parent, _name), group(_group)
43 {
44
45 }
46
~H5Group()47 H5Group::~H5Group()
48 {
49 if (group >= 0)
50 {
51 H5Gclose(group);
52 }
53 }
54
getSoftLinks()55 H5NamedObjectsList<H5SoftLink> & H5Group::getSoftLinks()
56 {
57 return *new H5NamedObjectsList<H5SoftLink>(*this, -1, H5L_TYPE_SOFT, "Soft Link");
58 }
59
getExternalLinks()60 H5NamedObjectsList<H5ExternalLink> & H5Group::getExternalLinks()
61 {
62 return *new H5NamedObjectsList<H5ExternalLink>(*this, -1, H5L_TYPE_EXTERNAL, "External Link");
63 }
64
getGroups()65 H5GroupsList & H5Group::getGroups()
66 {
67 return *new H5GroupsList(*this);
68 }
69
getHardGroups()70 H5NamedObjectsList<H5Group> & H5Group::getHardGroups()
71 {
72 return *new H5NamedObjectsList<H5Group>(*this, H5O_TYPE_GROUP, H5L_TYPE_HARD, "Group");
73 }
74
getHardTypes()75 H5NamedObjectsList<H5Type> & H5Group::getHardTypes()
76 {
77 return *new H5NamedObjectsList<H5Type>(*this, H5O_TYPE_NAMED_DATATYPE, H5L_TYPE_HARD, "Type");
78 }
79
getHardDatasets()80 H5NamedObjectsList<H5Dataset> & H5Group::getHardDatasets()
81 {
82 return *new H5NamedObjectsList<H5Dataset>(*this, H5O_TYPE_DATASET, H5L_TYPE_HARD, "Dataset");
83 }
84
getDatasets()85 H5DatasetsList & H5Group::getDatasets()
86 {
87 return *new H5DatasetsList(*this);
88 }
89
getTypes()90 H5TypesList & H5Group::getTypes()
91 {
92 return *new H5TypesList(*this);
93 }
94
getLinksSize() const95 unsigned int H5Group::getLinksSize() const
96 {
97 herr_t err;
98 H5G_info_t info;
99
100 err = H5Gget_info(group, &info);
101 if (err < 0)
102 {
103 throw H5Exception(__LINE__, __FILE__, _("Cannot get the links number"));
104 }
105
106 return (unsigned int)info.nlinks;
107 }
108
getCompletePath() const109 std::string H5Group::getCompletePath() const
110 {
111 std::string name = getName();
112 if (name == "/")
113 {
114 return "/";
115 }
116
117 return H5Object::getCompletePath();
118 }
119
getAccessibleAttribute(const std::string & _name,const int pos,void * pvApiCtx) const120 void H5Group::getAccessibleAttribute(const std::string & _name, const int pos, void * pvApiCtx) const
121 {
122 SciErr err;
123 std::string lower(_name);
124
125 std::transform(_name.begin(), _name.end(), lower.begin(), tolower);
126
127 if (lower == "attributes")
128 {
129 std::vector<std::string> names;
130 getNames(*this, names, ATTRIBUTE);
131 H5BasicData<char>::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx);
132
133 return;
134 }
135 else if (lower == "groups")
136 {
137 std::vector<std::string> names;
138 getNames(*this, names, GROUP);
139 H5BasicData<char>::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx);
140
141 return;
142 }
143 else if (lower == "datasets")
144 {
145 std::vector<std::string> names;
146 getNames(*this, names, DATASET);
147 H5BasicData<char>::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx);
148
149 return;
150 }
151 else if (lower == "types")
152 {
153 std::vector<std::string> names;
154 getNames(*this, names, TYPE);
155 H5BasicData<char>::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx);
156
157 return;
158 }
159 else if (lower == "externals")
160 {
161 std::vector<std::string> names;
162 getNames(*this, names, EXTERNAL);
163 H5BasicData<char>::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx);
164
165 return;
166 }
167 else if (lower == "softs")
168 {
169 std::vector<std::string> names;
170 getNames(*this, names, SOFT);
171 H5BasicData<char>::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx);
172
173 return;
174 }
175 else if (lower == "danglings")
176 {
177 std::vector<std::string> names;
178 getNames(*this, names, DANGLING);
179 H5BasicData<char>::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx);
180
181 return;
182 }
183 else if (lower == "hards")
184 {
185 std::vector<std::string> names;
186 getNames(*this, names, HARD);
187 H5BasicData<char>::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx);
188
189 return;
190 }
191 else if (lower == "links")
192 {
193 std::vector<std::string> names;
194 std::vector<std::string> types;
195 std::vector<std::string> linkstype;
196 std::vector<const char *> _str;
197 H5Object::getLinksInfo(*this, names, types, linkstype);
198 _str.reserve(names.size() * 3);
199
200 for (unsigned int i = 0; i < names.size(); i++)
201 {
202 _str.push_back(names[i].c_str());
203 }
204 for (unsigned int i = 0; i < names.size(); i++)
205 {
206 _str.push_back(linkstype[i].c_str());
207 }
208 for (unsigned int i = 0; i < names.size(); i++)
209 {
210 _str.push_back(types[i].c_str());
211 }
212
213 err = createMatrixOfString(pvApiCtx, pos, (int)names.size(), 3, &(_str[0]));
214 if (err.iErr)
215 {
216 throw H5Exception(__LINE__, __FILE__, _("Cannot create a column of strings on the stack."));
217 }
218
219 return;
220 }
221 else
222 {
223 try
224 {
225 H5Object & obj = H5Object::getObject(*const_cast<H5Group *>(this), _name);
226 obj.createOnScilabStack(pos, pvApiCtx);
227 return;
228 }
229 catch (const H5Exception & /*e*/) { }
230 }
231
232 H5Object::getAccessibleAttribute(_name, pos, pvApiCtx);
233 }
234
ls(std::vector<std::string> & name,std::vector<std::string> & type) const235 void H5Group::ls(std::vector<std::string> & name, std::vector<std::string> & type) const
236 {
237 herr_t err;
238 OpDataGetLs opdata(const_cast<H5Group *>(this), &name, &type);
239 hsize_t idx = 0;
240
241 err = H5Literate(group, H5_INDEX_NAME, H5_ITER_INC, &idx, getLsInfo, &opdata);
242 if (err < 0)
243 {
244 throw H5Exception(__LINE__, __FILE__, _("Cannot list group links."));
245 }
246
247 idx = 0;
248 err = H5Aiterate(group, H5_INDEX_NAME, H5_ITER_INC, &idx, H5Object::getLsAttributes, &opdata);
249 if (err < 0)
250 {
251 throw H5Exception(__LINE__, __FILE__, _("Cannot list group attributes."));
252 }
253 }
254
getLsInfo(hid_t g_id,const char * name,const H5L_info_t * info,void * op_data)255 herr_t H5Group::getLsInfo(hid_t g_id, const char * name, const H5L_info_t * info, void * op_data)
256 {
257 H5O_info_t oinfo;
258 herr_t err;
259 hid_t obj;
260 OpDataGetLs & opdata = *(OpDataGetLs *)op_data;
261
262 switch (info->type)
263 {
264 case H5L_TYPE_SOFT:
265 opdata.name->push_back(name);
266 opdata.type->push_back("soft");
267 break;
268 case H5L_TYPE_EXTERNAL:
269 opdata.name->push_back(name);
270 opdata.type->push_back("external");
271 break;
272 case H5L_TYPE_HARD:
273 obj = H5Oopen_by_addr(g_id, info->u.address);
274 if (obj < 0)
275 {
276 return (herr_t) - 1;
277 }
278
279 err = H5Oget_info(obj, &oinfo);
280 H5Oclose(obj);
281 if (err < 0)
282 {
283 return (herr_t) - 1;
284 }
285
286 switch (oinfo.type)
287 {
288 case H5O_TYPE_GROUP:
289 opdata.name->push_back(name);
290 opdata.type->push_back("group");
291 break;
292 case H5O_TYPE_DATASET:
293 opdata.name->push_back(name);
294 opdata.type->push_back("dataset");
295 break;
296 case H5O_TYPE_NAMED_DATATYPE:
297 opdata.name->push_back(name);
298 opdata.type->push_back("type");
299 break;
300 default:
301 return (herr_t) - 1;
302 }
303 break;
304 default:
305 return (herr_t) - 1;
306 }
307
308 return (herr_t)0;
309 }
310
ls() const311 std::string H5Group::ls() const
312 {
313 std::ostringstream os;
314 herr_t err;
315 OpDataPrintLs opdata;
316 opdata.parent = const_cast<H5Group *>(this);
317 opdata.os = &os;
318 hsize_t idx = 0;
319
320 err = H5Literate(group, H5_INDEX_NAME, H5_ITER_INC, &idx, printLsInfo, &opdata);
321 if (err < 0)
322 {
323 throw H5Exception(__LINE__, __FILE__, _("Cannot list group contents"));
324 }
325
326 return os.str();
327 }
328
printLsInfo(hid_t g_id,const char * name,const H5L_info_t * info,void * op_data)329 herr_t H5Group::printLsInfo(hid_t g_id, const char * name, const H5L_info_t * info, void * op_data)
330 {
331 H5O_info_t oinfo;
332 herr_t err;
333 H5Object * hobj = 0;
334 hid_t obj = 0;
335 OpDataPrintLs & opdata = *(OpDataPrintLs *)op_data;
336
337 switch (info->type)
338 {
339 case H5L_TYPE_SOFT:
340 hobj = new H5SoftLink(*opdata.parent, name);
341 break;
342 case H5L_TYPE_EXTERNAL:
343 hobj = new H5ExternalLink(*opdata.parent, name);
344 break;
345 case H5L_TYPE_HARD:
346 obj = H5Oopen(g_id, name, H5P_DEFAULT);
347 err = H5Oget_info(obj, &oinfo);
348 H5Oclose(obj);
349
350 if (err < 0)
351 {
352 return (herr_t) - 1;
353 }
354
355 switch (oinfo.type)
356 {
357 case H5O_TYPE_GROUP:
358 hobj = new H5Group(*opdata.parent, name);
359 break;
360 case H5O_TYPE_DATASET:
361 hobj = new H5Dataset(*opdata.parent, name);
362 break;
363 case H5O_TYPE_NAMED_DATATYPE:
364 hobj = new H5Type(*opdata.parent, name);
365 break;
366 default:
367 return (herr_t) - 1;
368 }
369 break;
370 default:
371 return (herr_t) - 1;
372 }
373
374 hobj->printLsInfo(*opdata.os);
375 delete hobj;
376
377 return (herr_t)0;
378 }
379
printLsInfo(std::ostringstream & os) const380 void H5Group::printLsInfo(std::ostringstream & os) const
381 {
382 std::string str(getName());
383 H5Object::getResizedString(str);
384
385 os << str << "Group" << std::endl;
386 }
387
dump(std::map<haddr_t,std::string> & alreadyVisited,const unsigned int indentLevel) const388 std::string H5Group::dump(std::map<haddr_t, std::string> & alreadyVisited, const unsigned int indentLevel) const
389 {
390 std::ostringstream os;
391 haddr_t addr = this->getAddr();
392 std::map<haddr_t, std::string>::iterator it = alreadyVisited.find(addr);
393 if (it != alreadyVisited.end())
394 {
395 os << H5Object::getIndentString(indentLevel) << "GROUP \"" << getName() << "\" {" << std::endl
396 << H5Object::getIndentString(indentLevel + 1) << "HARDLINK \"" << it->second << "\"" << std::endl
397 << H5Object::getIndentString(indentLevel) << "}" << std::endl;
398
399 return os.str();
400 }
401 else
402 {
403 alreadyVisited.insert(std::pair<haddr_t, std::string>(addr, getCompletePath()));
404 }
405
406 H5AttributesList & attrs = const_cast<H5Group *>(this)->getAttributes();
407 H5NamedObjectsList<H5SoftLink> & softlinks = const_cast<H5Group *>(this)->getSoftLinks();
408 H5NamedObjectsList<H5ExternalLink> & externallinks = const_cast<H5Group *>(this)->getExternalLinks();
409 H5NamedObjectsList<H5Group> & hardgroups = const_cast<H5Group *>(this)->getHardGroups();
410 H5NamedObjectsList<H5Type> & hardtypes = const_cast<H5Group *>(this)->getHardTypes();
411 H5NamedObjectsList<H5Dataset> & harddatasets = const_cast<H5Group *>(this)->getHardDatasets();
412
413 os << H5Object::getIndentString(indentLevel) << "GROUP \"" << name << "\" {" << std::endl;
414 os << attrs.dump(alreadyVisited, indentLevel + 1);
415 os << hardgroups.dump(alreadyVisited, indentLevel + 1);
416 os << hardtypes.dump(alreadyVisited, indentLevel + 1);
417 os << harddatasets.dump(alreadyVisited, indentLevel + 1);
418 os << softlinks.dump(alreadyVisited, indentLevel + 1);
419 os << externallinks.dump(alreadyVisited, indentLevel + 1);
420 os << H5Object::getIndentString(indentLevel) << "}" << std::endl;
421
422 delete &attrs;
423 delete &softlinks;
424 delete &externallinks;
425 delete &hardgroups;
426 delete &hardtypes;
427 delete &harddatasets;
428
429 return os.str();
430 }
431
toString(const unsigned int indentLevel) const432 std::string H5Group::toString(const unsigned int indentLevel) const
433 {
434 std::ostringstream os;
435 std::string indentString = H5Object::getIndentString(indentLevel + 1);
436 OpDataCount opdata(false);
437 H5Object::count(*this, opdata);
438
439 os << H5Object::getIndentString(indentLevel) << "HDF5 Group" << std::endl
440 << indentString << "Filename" << ": " << getFile().getFileName() << std::endl
441 << indentString << "Name" << ": " << getBaseName() << std::endl
442 << indentString << "Path" << ": " << getCompletePath() << std::endl
443 << indentString << "Attributes" << ": [1 x " << getAttributesNumber() << "]" << std::endl
444 << indentString << "Groups" << ": [1 x " << opdata.group << "]" << std::endl
445 << indentString << "Datasets" << ": [1 x " << opdata.dataset << "]" << std::endl
446 << indentString << "Types" << ": [1 x " << opdata.type << "]" << std::endl
447 << indentString << "Externals" << ": [1 x " << opdata.external << "]" << std::endl
448 << indentString << "Softs" << ": [1 x " << opdata.soft << "]";
449
450 return os.str();
451 }
452
createGroup(H5Object & parent,const std::string & name)453 void H5Group::createGroup(H5Object & parent, const std::string & name)
454 {
455 const char * _name = name.c_str();
456 createGroup(parent, 1, &_name);
457 }
458
createGroup(H5Object & parent,const int size,const char ** names)459 void H5Group::createGroup(H5Object & parent, const int size, const char ** names)
460 {
461 hid_t obj;
462 hid_t loc = parent.getH5Id();
463
464 for (unsigned int i = 0; i < (unsigned int)size; i++)
465 {
466 if (H5Lexists(loc, names[i], H5P_DEFAULT) > 0)
467 {
468 throw H5Exception(__LINE__, __FILE__, _("The group already exists: %s."), names[i]);
469 }
470
471 obj = H5Gcreate(loc, names[i], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
472 if (obj < 0)
473 {
474 throw H5Exception(__LINE__, __FILE__, _("Cannot create the group: %s."), names[i]);
475 }
476 H5Gclose(obj);
477 }
478 }
479 }
480