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 #ifndef __H5NAMEDOBJECTSLIST_HXX__ 17 #define __H5NAMEDOBJECTSLIST_HXX__ 18 19 #include "H5Object.hxx" 20 #include "H5File.hxx" 21 #include "H5Link.hxx" 22 #include "H5ListObject.hxx" 23 24 #include "os_string.h" 25 26 namespace org_modules_hdf5 27 { 28 29 class H5Group; 30 31 template <typename T> 32 class H5NamedObjectsList : public H5ListObject<T> 33 { 34 35 typedef struct 36 { 37 union 38 { 39 unsigned int count; 40 const char * name; 41 } u; 42 int linktype; 43 int basetype; 44 } OpData; 45 46 47 public : 48 H5NamedObjectsList(H5Group & _parent,const int _baseType,const int _linkType,const std::string _baseTypeName)49 H5NamedObjectsList(H5Group & _parent, const int _baseType, const int _linkType, const std::string _baseTypeName) : H5ListObject<T>(_parent), baseType(_baseType), linkType(_linkType), baseTypeName(_baseTypeName), prevPos(0), idx(0) { } 50 H5NamedObjectsList(H5Group & _parent,const unsigned int _size,const unsigned int * _index,const int _baseType,const int _linkType,const std::string _baseTypeName)51 H5NamedObjectsList(H5Group & _parent, const unsigned int _size, const unsigned int * _index, const int _baseType, const int _linkType, const std::string _baseTypeName) : H5ListObject<T>(_parent, _size, _index), baseType(_baseType), linkType(_linkType), baseTypeName(_baseTypeName), prevPos(0), idx(0) 52 { 53 const unsigned int lsize = getSize(true); 54 for (unsigned int i = 0; i < H5ListObject<T>::indexSize; i++) 55 { 56 if (H5ListObject<T>::indexList[i] >= lsize) 57 { 58 throw H5Exception(__LINE__, __FILE__, _("Invalid index at position %d"), i); 59 } 60 } 61 } 62 ~H5NamedObjectsList()63 virtual ~H5NamedObjectsList() 64 { 65 66 } 67 setObject(const unsigned int pos,T & obj)68 void setObject(const unsigned int pos, T & obj) 69 { 70 71 } 72 getObject(const int pos)73 T & getObject(const int pos) 74 { 75 return getObject(pos, true); 76 } 77 count(hid_t g_id,const char * name,const H5L_info_t * info,void * op_data)78 inline static herr_t count(hid_t g_id, const char * name, const H5L_info_t * info, void * op_data) 79 { 80 OpData & opdata = *(OpData *)op_data; 81 82 if ((opdata.linktype != -1 && info->type == opdata.linktype) || (opdata.linktype == -1 && info->type != H5L_TYPE_ERROR)) 83 { 84 H5O_info_t oinfo; 85 herr_t err; 86 if (opdata.basetype != -1) 87 { 88 hid_t obj = H5Oopen(g_id, name, H5P_DEFAULT); 89 90 if (obj < 0) 91 { 92 return (herr_t) - 1; 93 } 94 95 err = H5Oget_info(obj, &oinfo); 96 H5Oclose(obj); 97 98 if (err < 0) 99 { 100 return (herr_t) - 2; 101 } 102 103 if (oinfo.type == opdata.basetype) 104 { 105 opdata.u.count++; 106 } 107 } 108 else 109 { 110 opdata.u.count++; 111 } 112 } 113 114 return (herr_t)0; 115 } 116 getElement(hid_t g_id,const char * name,const H5L_info_t * info,void * op_data)117 inline static herr_t getElement(hid_t g_id, const char * name, const H5L_info_t * info, void * op_data) 118 { 119 OpData & opdata = *(OpData *)op_data; 120 121 if ((opdata.linktype != -1 && info->type == opdata.linktype) || (opdata.linktype == -1 && info->type != H5L_TYPE_ERROR)) 122 { 123 H5O_info_t oinfo; 124 herr_t err; 125 if (opdata.basetype != -1) 126 { 127 hid_t obj = H5Oopen(g_id, name, H5P_DEFAULT); 128 129 if (obj < 0) 130 { 131 return (herr_t) - 1; 132 } 133 134 err = H5Oget_info(obj, &oinfo); 135 H5Oclose(obj); 136 137 if (err < 0) 138 { 139 return (herr_t) - 2; 140 } 141 142 if (oinfo.type == opdata.basetype) 143 { 144 opdata.u.count--; 145 } 146 } 147 else 148 { 149 opdata.u.count--; 150 } 151 152 if (opdata.u.count == 0) 153 { 154 opdata.u.name = os_strdup(name); 155 156 return (herr_t)1; 157 } 158 } 159 160 return (herr_t)0; 161 } 162 getSize() const163 unsigned int getSize() const 164 { 165 return getSize(false); 166 } 167 getSize(const bool indexChecking) const168 unsigned int getSize(const bool indexChecking) const 169 { 170 if (H5ListObject<T>::indexList && !indexChecking) 171 { 172 return H5ListObject<T>::indexSize; 173 } 174 else 175 { 176 hsize_t idx = 0; 177 OpData op_data; 178 herr_t err; 179 180 op_data.u.count = 0; 181 op_data.linktype = linkType; 182 op_data.basetype = baseType; 183 184 err = H5Literate(H5Object::getParent().getH5Id(), H5_INDEX_NAME, H5_ITER_INC, &idx, count, &op_data); 185 186 if (err < 0) 187 { 188 throw H5Exception(__LINE__, __FILE__, _("Cannot get the number of objects.")); 189 } 190 191 return op_data.u.count; 192 } 193 } 194 dump(std::map<haddr_t,std::string> & alreadyVisited,const unsigned int indentLevel) const195 virtual std::string dump(std::map<haddr_t, std::string> & alreadyVisited, const unsigned int indentLevel) const 196 { 197 std::ostringstream os; 198 const unsigned int size = getSize(); 199 200 for (unsigned int i = 0; i < size; i++) 201 { 202 const T & obj = const_cast<H5NamedObjectsList *>(this)->getObject(i, false); 203 os << obj.dump(alreadyVisited, indentLevel); 204 205 delete &obj; 206 } 207 208 return os.str(); 209 } 210 printLsInfo(std::ostringstream & os) const211 virtual void printLsInfo(std::ostringstream & os) const 212 { 213 const unsigned int size = getSize(); 214 215 for (unsigned int i = 0; i < size; i++) 216 { 217 const T & obj = const_cast<H5NamedObjectsList *>(this)->getObject(i, false); 218 obj.printLsInfo(os); 219 220 delete &obj; 221 } 222 } 223 toString(const unsigned int indentLevel) const224 virtual std::string toString(const unsigned int indentLevel) const 225 { 226 std::ostringstream os; 227 std::string indentString = H5Object::getIndentString(indentLevel); 228 const unsigned int size = getSize(); 229 230 os << indentString << _("Filename") << ": " << H5Object::getParent().getFile().getFileName() << std::endl 231 << indentString << _("Parent group name") << ": " << H5Object::getParent().getName() << std::endl 232 << indentString << _("Parent group path") << ": " << H5Object::getParent().getCompletePath() << std::endl 233 << indentString << _("Elements type") << ": " << baseTypeName << std::endl 234 << indentString << _("Size") << ": " << size; 235 236 return os.str(); 237 } 238 239 protected : 240 241 const int baseType; 242 const int linkType; 243 const std::string baseTypeName; 244 245 private : 246 247 int prevPos; 248 hsize_t idx; 249 250 251 private: 252 getObject(const int pos,const bool checkPos)253 T & getObject(const int pos, const bool checkPos) 254 { 255 OpData op_data; 256 herr_t err; 257 int _pos = pos; 258 259 if (H5ListObject<T>::indexList) 260 { 261 if (pos >= 0 && pos < (int)H5ListObject<T>::indexSize) 262 { 263 _pos = H5ListObject<T>::indexList[pos]; 264 } 265 else 266 { 267 throw H5Exception(__LINE__, __FILE__, _("Invalid index: %d."), pos); 268 } 269 } 270 271 op_data.linktype = linkType; 272 op_data.basetype = baseType; 273 274 if (_pos < prevPos) 275 { 276 idx = 0; 277 op_data.u.count = _pos + 1; 278 } 279 else 280 { 281 op_data.u.count = _pos - prevPos + 1; 282 } 283 284 err = H5Literate(H5Object::getParent().getH5Id(), H5_INDEX_NAME, H5_ITER_INC, &idx, getElement, &op_data); 285 286 if (err > 0) 287 { 288 prevPos = _pos + 1; 289 return *new T(H5Object::getParent(), op_data.u.name); 290 } 291 else 292 { 293 idx = 0; 294 prevPos = 0; 295 throw H5Exception(__LINE__, __FILE__, _("Cannot get object at position %d."), pos); 296 } 297 } 298 getObject(const std::string & name)299 T & getObject(const std::string & name) 300 { 301 H5O_info_t info; 302 herr_t err; 303 H5Object * obj = 0; 304 305 if (H5Lexists(H5Object::getParent().getH5Id(), name.c_str(), H5P_DEFAULT) <= 0) 306 { 307 throw H5Exception(__LINE__, __FILE__, _("Invalid name: %s."), name.c_str()); 308 } 309 310 err = H5Oget_info_by_name(H5Object::getParent().getH5Id(), name.c_str(), &info, H5P_DEFAULT); 311 if (err < 0) 312 { 313 throw H5Exception(__LINE__, __FILE__, _("Invalid name: %s."), name.c_str()); 314 } 315 316 if (info.type == baseType) 317 { 318 return *new T(H5Object::getParent(), name); 319 } 320 321 throw H5Exception(__LINE__, __FILE__, _("Invalid HDF5 object")); 322 } 323 }; 324 } 325 326 #endif // __H5NAMEDOBJECTSLIST_HXX__ 327