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 #ifdef _MSC_VER
17 #pragma warning(disable: 4355) //disable Warning C4355: 'this' : used in base member initializer list
18 #endif
19 
20 #ifndef __H5OBJECT_HXX__
21 #define __H5OBJECT_HXX__
22 
23 #include "HDF5Objects.h"
24 
25 #include <algorithm>
26 #include <cstdlib>
27 #include <iostream>
28 #include <iomanip>
29 #include <limits>
30 #include <map>
31 #include <set>
32 #include <string>
33 
34 extern "C"
35 {
36 #include "sci_malloc.h"
37 #include "Scierror.h"
38 #include "api_scilab.h"
39 #include "localization.h"
40 }
41 
42 #include "H5VariableScope.hxx"
43 #include "H5Exception.hxx"
44 
45 #define __H5_INDENT_LENGTH__ 3
46 #define __H5_LS_LENGTH__ 25
47 
48 namespace org_modules_hdf5
49 {
50 class H5AttributesList;
51 class H5File;
52 
53 class H5Object
54 {
55     static H5Object* root;
56 
57     H5Object & parent;
58     std::set<H5Object *> children;
59     bool locked;
60     int scilabId;
61 
62     friend class H5AttributesList;
63     friend class H5LinkList;
64     friend class H5Dataset;
65 
66 protected: // for error report only
67 
68     const std::string name;
69 
70 public :
71 
72     enum FilterType {HARD, SOFT, EXTERNAL, DANGLING, GROUP, DATASET, TYPE, ATTRIBUTE};
73 
74     H5Object(H5Object & _parent);
75     H5Object(H5Object & _parent, const std::string & _name);
76     virtual ~H5Object();
77 
clearRoot()78     static void clearRoot()
79     {
80         delete root;
81     }
82 
initRoot()83     static void initRoot()
84     {
85         root = new H5Object();
86     }
87 
88     virtual void cleanup();
89 
90     virtual hid_t getH5Id() const;
91     virtual H5AttributesList & getAttributes();
92     virtual hsize_t getAttributesNumber() const;
93 
getInfo() const94     virtual H5O_info_t getInfo() const
95     {
96         H5O_info_t info;
97         H5Oget_info(getH5Id(), &info);
98 
99         return info;
100     }
101 
isFile() const102     virtual bool isFile() const
103     {
104         return false;
105     }
106 
isGroup() const107     virtual bool isGroup() const
108     {
109         return false;
110     }
111 
isAttribute() const112     virtual bool isAttribute() const
113     {
114         return false;
115     }
116 
isReference() const117     virtual bool isReference() const
118     {
119         return false;
120     }
121 
isDataspace() const122     virtual bool isDataspace() const
123     {
124         return false;
125     }
126 
isDataset() const127     virtual bool isDataset() const
128     {
129         return false;
130     }
131 
isType() const132     virtual bool isType() const
133     {
134         return false;
135     }
136 
isList() const137     virtual bool isList() const
138     {
139         return false;
140     }
141 
isCompound() const142     virtual bool isCompound() const
143     {
144         return false;
145     }
146 
isArray() const147     virtual bool isArray() const
148     {
149         return false;
150     }
151 
isVlen() const152     virtual bool isVlen() const
153     {
154         return false;
155     }
156 
mustDelete() const157     virtual bool mustDelete() const
158     {
159         return true;
160     }
161 
getAddr() const162     virtual haddr_t getAddr() const
163     {
164         return getInfo().addr;
165     }
166 
getName() const167     virtual const std::string & getName() const
168     {
169         return name;
170     }
171 
getData(const unsigned int size,const unsigned int * index) const172     virtual H5Object & getData(const unsigned int size, const unsigned int * index) const
173     {
174         throw H5Exception(__LINE__, __FILE__, _("Cannot retrieve numeric index."));
175     }
176 
getData(const unsigned int size,const double * index) const177     virtual H5Object & getData(const unsigned int size, const double * index) const
178     {
179         unsigned int * _index = new unsigned int[size];
180         for (unsigned int i = 0; i < size; i++)
181         {
182             _index[i] = (unsigned int)(index[i] - 1);
183         }
184 
185         try
186         {
187             return getData(size, _index);
188         }
189         catch (const H5Exception & /*e*/)
190         {
191             delete[] _index;
192             throw;
193         }
194     }
195 
196 
getBaseName() const197     virtual const std::string getBaseName() const
198     {
199         std::string::size_type pos = name.find_last_of('/');
200         if (pos == std::string::npos)
201         {
202             return name;
203         }
204         else
205         {
206             return name.substr(pos + 1);
207         }
208     }
209 
210     virtual std::string getCompletePath() const;
dump(std::map<haddr_t,std::string> & alreadyVisited,const unsigned int indentLevel=0) const211     virtual std::string dump(std::map<haddr_t, std::string> & alreadyVisited, const unsigned int indentLevel = 0) const
212     {
213         return "";
214     }
215 
ls() const216     virtual std::string ls() const
217     {
218         return "";
219     }
220 
ls(std::vector<std::string> & name,std::vector<std::string> & type) const221     virtual void ls(std::vector<std::string> & name, std::vector<std::string> & type) const
222     {
223 
224     }
225 
ls(std::vector<std::string> & name,FilterType type) const226     virtual void ls(std::vector<std::string> & name, FilterType type) const
227     {
228         getNames(*this, name, type);
229     }
230 
printLsInfo(std::ostringstream & os) const231     virtual void printLsInfo(std::ostringstream & os) const
232     {
233         return;
234     }
235 
toString() const236     virtual std::string toString() const
237     {
238         return toString(0);
239     }
toString(const unsigned int indentLevel) const240     virtual std::string toString(const unsigned int indentLevel) const
241     {
242         return "";
243     }
244     virtual void getAccessibleAttribute(const std::string & _name, const int pos, void * pvApiCtx) const;
getAccessibleAttribute(const double index,const int pos,void * pvApiCtx) const245     virtual void getAccessibleAttribute(const double index, const int pos, void * pvApiCtx) const
246     {
247         throw H5Exception(__LINE__, __FILE__, _("Invalid operation"));
248     }
249 
setAccessibleAttribute(const std::string & name,const int pos,void * pvApiCtx) const250     virtual void setAccessibleAttribute(const std::string & name, const int pos, void * pvApiCtx) const
251     {
252         throw H5Exception(__LINE__, __FILE__, _("Invalid operation"));
253     }
254 
setAccessibleAttribute(const double index,const int pos,void * pvApiCtx) const255     virtual void setAccessibleAttribute(const double index, const int pos, void * pvApiCtx) const
256     {
257         throw H5Exception(__LINE__, __FILE__, _("Invalid operation"));
258     }
259 
setScilabId(const int id)260     void setScilabId(const int id)
261     {
262         scilabId = id;
263     }
264 
getScilabId() const265     int getScilabId() const
266     {
267         return scilabId;
268     }
269 
getParent() const270     H5Object & getParent() const
271     {
272         return parent;
273     }
274     H5File & getFile() const;
275 
276     virtual void getNames(const H5Object & obj, std::vector<std::string> & names, FilterType type) const;
277     virtual void createOnScilabStack(int pos, void * pvApiCtx) const;
278     virtual void createInScilabList(int * list, int stackPos, int pos, void * pvApiCtx) const;
279 
toScilab(void * pvApiCtx,const int lhsPosition,int * parentList=0,const int listPosition=0,const bool flip=true) const280     virtual void toScilab(void * pvApiCtx, const int lhsPosition, int * parentList = 0, const int listPosition = 0, const bool flip = true) const
281     {
282         if (parentList)
283         {
284             createInScilabList(parentList, lhsPosition, listPosition, pvApiCtx);
285         }
286         else
287         {
288             createOnScilabStack(lhsPosition, pvApiCtx);
289         }
290     }
291 
isRoot() const292     bool isRoot() const
293     {
294         return this == root;
295     }
296 
unregisterChild(H5Object * child)297     void unregisterChild(H5Object * child)
298     {
299         if (!locked)
300         {
301             children.erase(child);
302         }
303     }
304 
getIndentString(const unsigned int indentLevel)305     static std::string getIndentString(const unsigned int indentLevel)
306     {
307         return std::string((size_t)(__H5_INDENT_LENGTH__ * indentLevel), ' ');
308     }
309 
getRoot()310     static H5Object & getRoot()
311     {
312         return *root;
313     }
314 
cleanAll()315     static void cleanAll()
316     {
317         root->locked = true;
318         for (std::set<H5Object *>::iterator it = root->children.begin(); it != root->children.end(); it++)
319         {
320             delete *it;
321         }
322         root->children.clear();
323         root->locked = false;
324         H5VariableScope::clearScope();
325     }
326 
getResizedString(std::string & str)327     static void getResizedString(std::string & str)
328     {
329         if (str.length() < __H5_LS_LENGTH__)
330         {
331             str.resize(__H5_LS_LENGTH__, ' ');
332         }
333     }
334 
335     static H5Object & getObject(H5Object & parent, hid_t obj);
336     static H5Object & getObject(H5Object & parent, const std::string & name);
337     static H5Object & getObject(H5Object & parent, const std::string & name, const bool isAttr);
338     static void getLinksInfo(const H5Object & obj, std::vector<std::string> & linksName, std::vector<std::string> & types, std::vector<std::string> & linksType);
339 
getCumProd(const hsize_t ndims,const hsize_t * dims)340     inline static hsize_t * getCumProd(const hsize_t ndims, const hsize_t * dims)
341     {
342         hsize_t * ret = new hsize_t[ndims];
343         ret[0] = 1;
344         for (unsigned int i = 1; i < ndims; i++)
345         {
346             ret[i] *= ret[i - 1];
347         }
348 
349         return ret;
350     }
351 
isEmptyPath(const std::string & path)352     inline static bool isEmptyPath(const std::string & path)
353     {
354         return path.empty() || path == ".";
355     }
356 
isEmptyPath(const char * path)357     inline static bool isEmptyPath(const char * path)
358     {
359         return path[0] == '\0' || (path[0] == '.' && path[1] == '\0');
360     }
361 
362 protected :
363 
364     class OpDataGetLs
365     {
366     public:
367         H5Object * parent;
368         std::vector<std::string> * name;
369         std::vector<std::string> * type;
370 
OpDataGetLs(H5Object * _parent,std::vector<std::string> * _name,std::vector<std::string> * _type)371         OpDataGetLs(H5Object * _parent, std::vector<std::string> * _name, std::vector<std::string> * _type) : parent(_parent), name(_name), type(_type) { }
372     };
373 
374     class OpDataCount
375     {
376     public:
377         unsigned int soft;
378         unsigned int external;
379         unsigned int hard;
380         unsigned int dangling;
381         unsigned int group;
382         unsigned int dataset;
383         unsigned int type;
384         const bool followLink;
385 
OpDataCount(const bool _followLink)386         OpDataCount(const bool _followLink) : soft(0), external(0), hard(0), dangling(0), group(0), dataset(0), type(0), followLink(_followLink) { }
387     };
388 
389     class OpDataFilter
390     {
391     public:
392         std::vector<std::string> * name;
393         FilterType type;
394         const bool followLink;
395 
OpDataFilter(std::vector<std::string> * _name,FilterType _type,const bool _followLink)396         OpDataFilter(std::vector<std::string> * _name, FilterType _type, const bool _followLink) : name(_name), type(_type), followLink(_followLink) { }
397     };
398 
399     class OpDataSoftLinkFilter
400     {
401     public:
402         std::vector<std::string> * name;
403         std::vector<std::string> * value;
404         FilterType type;
405 
OpDataSoftLinkFilter(std::vector<std::string> * _name,std::vector<std::string> * _value,FilterType _type)406         OpDataSoftLinkFilter(std::vector<std::string> * _name, std::vector<std::string> * _value, FilterType _type) : name(_name), value(_value), type(_type) { }
407     };
408 
registerChild(H5Object * child)409     void registerChild(H5Object * child)
410     {
411         if (!locked)
412         {
413             children.insert(child);
414         }
415     }
416 
417     static void count(const H5Object & obj, OpDataCount & opdata);
418     static herr_t countIterator(hid_t g_id, const char * name, const H5L_info_t * info, void * op_data);
419     static herr_t filterAttributesIterator(hid_t location_id, const char * attr_name, const H5A_info_t * ainfo, void * op_data);
420     static herr_t filterIterator(hid_t g_id, const char * name, const H5L_info_t * info, void * op_data);
421     static herr_t filterSoftLinkIterator(hid_t g_id, const char * name, const H5L_info_t * info, void * op_data);
422     static herr_t getLsAttributes(hid_t location_id, const char * attr_name, const H5A_info_t * ainfo, void * op_data);
423 
424 private :
425 
H5Object()426     H5Object() : parent(*this), locked(false), scilabId(-1) { }
427 
428     class LinksInfo
429     {
430     public:
431         std::vector<std::string> * name;
432         std::vector<std::string> * type;
433         std::vector<std::string> * linkType;
434 
LinksInfo(std::vector<std::string> * _name,std::vector<std::string> * _type,std::vector<std::string> * _linkType)435         LinksInfo(std::vector<std::string> * _name, std::vector<std::string> * _type, std::vector<std::string> * _linkType) : name(_name), type(_type), linkType(_linkType) { }
436     };
437 
438     static herr_t iterateGetInfo(hid_t g_id, const char * name, const H5L_info_t * info, void * op_data);
439 };
440 }
441 
442 #undef __H5_INDENT_LENGTH__
443 #undef __H5_LS_LENGTH__
444 
445 #endif // __H5OBJECT_HXX__
446 
447