/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt * */ #include "H5Group.hxx" #include "H5File.hxx" #include "H5SoftLinksList.hxx" #include "H5GroupsList.hxx" #include "H5DatasetsList.hxx" #include "H5TypesList.hxx" #include "H5Link.hxx" #include "H5BasicData.hxx" namespace org_modules_hdf5 { void H5Group::init() { group = H5Gopen(getParent().getH5Id(), name.c_str(), H5P_DEFAULT); if (group < 0) { throw H5Exception(__LINE__, __FILE__, _("Cannot open the group %s."), name.c_str()); } } H5Group::H5Group(H5Object & _parent, const std::string & _name) : H5Object(_parent, _name) { init(); } H5Group::H5Group(H5Object & _parent, hid_t _group, const std::string & _name) : H5Object(_parent, _name), group(_group) { } H5Group::~H5Group() { if (group >= 0) { H5Gclose(group); } } H5NamedObjectsList & H5Group::getSoftLinks() { return *new H5NamedObjectsList(*this, -1, H5L_TYPE_SOFT, "Soft Link"); } H5NamedObjectsList & H5Group::getExternalLinks() { return *new H5NamedObjectsList(*this, -1, H5L_TYPE_EXTERNAL, "External Link"); } H5GroupsList & H5Group::getGroups() { return *new H5GroupsList(*this); } H5NamedObjectsList & H5Group::getHardGroups() { return *new H5NamedObjectsList(*this, H5O_TYPE_GROUP, H5L_TYPE_HARD, "Group"); } H5NamedObjectsList & H5Group::getHardTypes() { return *new H5NamedObjectsList(*this, H5O_TYPE_NAMED_DATATYPE, H5L_TYPE_HARD, "Type"); } H5NamedObjectsList & H5Group::getHardDatasets() { return *new H5NamedObjectsList(*this, H5O_TYPE_DATASET, H5L_TYPE_HARD, "Dataset"); } H5DatasetsList & H5Group::getDatasets() { return *new H5DatasetsList(*this); } H5TypesList & H5Group::getTypes() { return *new H5TypesList(*this); } const unsigned int H5Group::getLinksSize() const { herr_t err; H5G_info_t info; err = H5Gget_info(group, &info); if (err < 0) { throw H5Exception(__LINE__, __FILE__, _("Cannot get the links number")); } return (unsigned int)info.nlinks; } std::string H5Group::getCompletePath() const { std::string name = getName(); if (name == "/") { return "/"; } return H5Object::getCompletePath(); } void H5Group::getAccessibleAttribute(const std::string & _name, const int pos, void * pvApiCtx) const { SciErr err; std::string lower(_name); std::transform(_name.begin(), _name.end(), lower.begin(), tolower); if (lower == "attributes") { std::vector names; getNames(*this, names, ATTRIBUTE); H5BasicData::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx); return; } else if (lower == "groups") { std::vector names; getNames(*this, names, GROUP); H5BasicData::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx); return; } else if (lower == "datasets") { std::vector names; getNames(*this, names, DATASET); H5BasicData::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx); return; } else if (lower == "types") { std::vector names; getNames(*this, names, TYPE); H5BasicData::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx); return; } else if (lower == "externals") { std::vector names; getNames(*this, names, EXTERNAL); H5BasicData::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx); return; } else if (lower == "softs") { std::vector names; getNames(*this, names, SOFT); H5BasicData::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx); return; } else if (lower == "danglings") { std::vector names; getNames(*this, names, DANGLING); H5BasicData::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx); return; } else if (lower == "hards") { std::vector names; getNames(*this, names, HARD); H5BasicData::putStringVectorOnStack(names, (int)names.size(), 1, pos, pvApiCtx); return; } else if (lower == "links") { std::vector names; std::vector types; std::vector linkstype; std::vector _str; H5Object::getLinksInfo(*this, names, types, linkstype); _str.reserve(names.size() * 3); for (unsigned int i = 0; i < names.size(); i++) { _str.push_back(names[i].c_str()); } for (unsigned int i = 0; i < names.size(); i++) { _str.push_back(linkstype[i].c_str()); } for (unsigned int i = 0; i < names.size(); i++) { _str.push_back(types[i].c_str()); } err = createMatrixOfString(pvApiCtx, pos, (int)names.size(), 3, &(_str[0])); if (err.iErr) { throw H5Exception(__LINE__, __FILE__, _("Cannot create a column of strings on the stack.")); } return; } else { try { H5Object & obj = H5Object::getObject(*const_cast(this), _name); obj.createOnScilabStack(pos, pvApiCtx); return; } catch (const H5Exception & /*e*/) { } } H5Object::getAccessibleAttribute(_name, pos, pvApiCtx); } void H5Group::ls(std::vector & name, std::vector & type) const { herr_t err; OpDataGetLs opdata(const_cast(this), &name, &type); hsize_t idx = 0; err = H5Literate(group, H5_INDEX_NAME, H5_ITER_INC, &idx, getLsInfo, &opdata); if (err < 0) { throw H5Exception(__LINE__, __FILE__, _("Cannot list group links.")); } idx = 0; err = H5Aiterate(group, H5_INDEX_NAME, H5_ITER_INC, &idx, H5Object::getLsAttributes, &opdata); if (err < 0) { throw H5Exception(__LINE__, __FILE__, _("Cannot list group attributes.")); } } herr_t H5Group::getLsInfo(hid_t g_id, const char * name, const H5L_info_t * info, void * op_data) { H5O_info_t oinfo; herr_t err; hid_t obj; OpDataGetLs & opdata = *(OpDataGetLs *)op_data; switch (info->type) { case H5L_TYPE_SOFT: opdata.name->push_back(name); opdata.type->push_back("soft"); break; case H5L_TYPE_EXTERNAL: opdata.name->push_back(name); opdata.type->push_back("external"); break; case H5L_TYPE_HARD: obj = H5Oopen_by_addr(g_id, info->u.address); if (obj < 0) { return (herr_t) - 1; } err = H5Oget_info(obj, &oinfo); H5Oclose(obj); if (err < 0) { return (herr_t) - 1; } switch (oinfo.type) { case H5O_TYPE_GROUP: opdata.name->push_back(name); opdata.type->push_back("group"); break; case H5O_TYPE_DATASET: opdata.name->push_back(name); opdata.type->push_back("dataset"); break; case H5O_TYPE_NAMED_DATATYPE: opdata.name->push_back(name); opdata.type->push_back("type"); break; default: return (herr_t) - 1; } break; default: return (herr_t) - 1; } return (herr_t)0; } std::string H5Group::ls() const { std::ostringstream os; herr_t err; OpDataPrintLs opdata; opdata.parent = const_cast(this); opdata.os = &os; hsize_t idx = 0; err = H5Literate(group, H5_INDEX_NAME, H5_ITER_INC, &idx, printLsInfo, &opdata); if (err < 0) { throw H5Exception(__LINE__, __FILE__, _("Cannot list group contents")); } return os.str(); } herr_t H5Group::printLsInfo(hid_t g_id, const char * name, const H5L_info_t * info, void * op_data) { H5O_info_t oinfo; herr_t err; H5Object * hobj = 0; hid_t obj = 0; OpDataPrintLs & opdata = *(OpDataPrintLs *)op_data; switch (info->type) { case H5L_TYPE_SOFT: hobj = new H5SoftLink(*opdata.parent, name); break; case H5L_TYPE_EXTERNAL: hobj = new H5ExternalLink(*opdata.parent, name); break; case H5L_TYPE_HARD: obj = H5Oopen(g_id, name, H5P_DEFAULT); err = H5Oget_info(obj, &oinfo); H5Oclose(obj); if (err < 0) { return (herr_t) - 1; } switch (oinfo.type) { case H5O_TYPE_GROUP: hobj = new H5Group(*opdata.parent, name); break; case H5O_TYPE_DATASET: hobj = new H5Dataset(*opdata.parent, name); break; case H5O_TYPE_NAMED_DATATYPE: hobj = new H5Type(*opdata.parent, name); break; default: return (herr_t) - 1; } break; default: return (herr_t) - 1; } hobj->printLsInfo(*opdata.os); delete hobj; return (herr_t)0; } void H5Group::printLsInfo(std::ostringstream & os) const { std::string str(getName()); H5Object::getResizedString(str); os << str << "Group" << std::endl; } std::string H5Group::dump(std::map & alreadyVisited, const unsigned int indentLevel) const { std::ostringstream os; haddr_t addr = this->getAddr(); std::map::iterator it = alreadyVisited.find(addr); if (it != alreadyVisited.end()) { os << H5Object::getIndentString(indentLevel) << "GROUP \"" << getName() << "\" {" << std::endl << H5Object::getIndentString(indentLevel + 1) << "HARDLINK \"" << it->second << "\"" << std::endl << H5Object::getIndentString(indentLevel) << "}" << std::endl; return os.str(); } else { alreadyVisited.insert(std::pair(addr, getCompletePath())); } H5AttributesList & attrs = const_cast(this)->getAttributes(); H5NamedObjectsList & softlinks = const_cast(this)->getSoftLinks(); H5NamedObjectsList & externallinks = const_cast(this)->getExternalLinks(); H5NamedObjectsList & hardgroups = const_cast(this)->getHardGroups(); H5NamedObjectsList & hardtypes = const_cast(this)->getHardTypes(); H5NamedObjectsList & harddatasets = const_cast(this)->getHardDatasets(); os << H5Object::getIndentString(indentLevel) << "GROUP \"" << name << "\" {" << std::endl; os << attrs.dump(alreadyVisited, indentLevel + 1); os << hardgroups.dump(alreadyVisited, indentLevel + 1); os << hardtypes.dump(alreadyVisited, indentLevel + 1); os << harddatasets.dump(alreadyVisited, indentLevel + 1); os << softlinks.dump(alreadyVisited, indentLevel + 1); os << externallinks.dump(alreadyVisited, indentLevel + 1); os << H5Object::getIndentString(indentLevel) << "}" << std::endl; delete &attrs; delete &softlinks; delete &externallinks; delete &hardgroups; delete &hardtypes; delete &harddatasets; return os.str(); } std::string H5Group::toString(const unsigned int indentLevel) const { std::ostringstream os; std::string indentString = H5Object::getIndentString(indentLevel + 1); OpDataCount opdata(false); H5Object::count(*this, opdata); os << H5Object::getIndentString(indentLevel) << "HDF5 Group" << std::endl << indentString << "Filename" << ": " << getFile().getFileName() << std::endl << indentString << "Name" << ": " << getBaseName() << std::endl << indentString << "Path" << ": " << getCompletePath() << std::endl << indentString << "Attributes" << ": [1 x " << getAttributesNumber() << "]" << std::endl << indentString << "Groups" << ": [1 x " << opdata.group << "]" << std::endl << indentString << "Datasets" << ": [1 x " << opdata.dataset << "]" << std::endl << indentString << "Types" << ": [1 x " << opdata.type << "]" << std::endl << indentString << "Externals" << ": [1 x " << opdata.external << "]" << std::endl << indentString << "Softs" << ": [1 x " << opdata.soft << "]"; return os.str(); } void H5Group::createGroup(H5Object & parent, const std::string & name) { const char * _name = name.c_str(); createGroup(parent, 1, &_name); } void H5Group::createGroup(H5Object & parent, const int size, const char ** names) { hid_t obj; hid_t loc = parent.getH5Id(); for (unsigned int i = 0; i < (unsigned int)size; i++) { if (H5Lexists(loc, names[i], H5P_DEFAULT) > 0) { throw H5Exception(__LINE__, __FILE__, _("The group already exists: %s."), names[i]); } obj = H5Gcreate(loc, names[i], H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if (obj < 0) { throw H5Exception(__LINE__, __FILE__, _("Cannot create the group: %s."), names[i]); } H5Gclose(obj); } } }