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 __H5DATACONVERTER_HXX__
17 #define __H5DATACONVERTER_HXX__
18 
19 #include "H5Exception.hxx"
20 #include "H5Object.hxx"
21 #include "H5Data.hxx"
22 
23 extern "C"
24 {
25 #include "api_scilab.h"
26 #include "Scierror.h"
27 #include "localization.h"
28 }
29 
30 namespace org_modules_hdf5
31 {
32 
33 class H5DataConverter
34 {
35 
36 public:
37 
dump(std::map<haddr_t,std::string> & alreadyVisited,const unsigned int indentLevel,const int ndims,const hsize_t * dims,const H5Data & obj,const bool line=true)38     static std::string dump(std::map<haddr_t, std::string> & alreadyVisited, const unsigned int indentLevel, const int ndims, const hsize_t * dims, const H5Data & obj, const bool line = true)
39     {
40         std::ostringstream os;
41         std::string indent = H5Object::getIndentString(indentLevel);
42         unsigned int pos = 0;
43 
44         os.setf(std::ios::fixed, std::ios::floatfield);
45         os.precision(1);
46 
47         os << indent << "DATA {" << std::endl;
48         printData(indentLevel, indent + "(", os, ndims, dims, &pos, obj, line);
49         os << indent << "}" << std::endl;
50 
51         return os.str();
52     }
53 
printData(const unsigned int indentLevel,const std::string & start,std::ostringstream & os,const int ndims,const hsize_t * dims,unsigned int * pos,const H5Data & obj,const bool line)54     static void printData(const unsigned int indentLevel, const std::string & start, std::ostringstream & os, const int ndims, const hsize_t * dims, unsigned int * pos, const H5Data & obj, const bool line)
55     {
56         std::string indent = H5Object::getIndentString(indentLevel);
57 
58         if (ndims == 0)
59         {
60             os << start << "0): ";
61             obj.printData(os, 0, 0);
62             os << std::endl;
63         }
64         else if (ndims == 1)
65         {
66             if (line)
67             {
68                 os << start << "0): ";
69                 for (hsize_t i = 0; i < dims[0] - 1; i++)
70                 {
71                     obj.printData(os, *pos + (int)i, 0);
72                     os << ", ";
73                 }
74                 obj.printData(os, *pos + (int)dims[0] - 1, 0);
75             }
76             else
77             {
78                 for (hsize_t i = 0; i < dims[0] - 1; i++)
79                 {
80                     os << start << i << "): ";
81                     obj.printData(os, *pos + (int)i, indentLevel);
82                     os << ", " << std::endl;
83                 }
84                 os << start << dims[0] - 1 << "): ";
85                 obj.printData(os, *pos + (int)dims[0] - 1, indentLevel);
86             }
87 
88             os << std::endl;
89             *pos += (int)dims[0];
90         }
91         else
92         {
93             std::ostringstream oss;
94             for (hsize_t i = 0; i < dims[0]; i++)
95             {
96                 oss << start << (unsigned int)i << ",";
97                 printData(indentLevel, oss.str(), os, ndims - 1, dims + 1, pos, obj, line);
98                 oss.str("");
99             }
100         }
101     }
102 
103     template <typename T>
C2FHypermatrix(const int ndims,const hsize_t * dims,const hsize_t size,const T * src,T * dest,const bool flip=true)104     static void C2FHypermatrix(const int ndims, const hsize_t * dims, const hsize_t size, const T * src, T * dest, const bool flip = true)
105     {
106         if (flip)
107         {
108             hsize_t totalSize = 1;
109             for (int i = 0; i < ndims; i++)
110             {
111                 totalSize *= dims[i];
112             }
113             memcpy(dest, src, totalSize * sizeof(T));
114         }
115         else
116         {
117             if (ndims == 2)
118             {
119                 for (int i = 0; i < dims[0]; i++)
120                 {
121                     for (int j = 0; j < dims[1]; j++)
122                     {
123                         dest[i + dims[0] * j] = src[j + dims[1] * i];
124                     }
125                 }
126             }
127             else
128             {
129                 hsize_t * cumprod = new hsize_t[ndims];
130                 hsize_t * cumdiv = new hsize_t[ndims];
131                 cumprod[0] = 1;
132                 cumdiv[ndims - 1] = 1;
133                 for (int i = 0; i < ndims - 1; i++)
134                 {
135                     cumprod[i + 1] = dims[i] * cumprod[i];
136                     cumdiv[i] = size / cumprod[i + 1];
137                 }
138 
139                 reorder(ndims, dims, cumprod, cumdiv, src, dest);
140                 delete[] cumprod;
141                 delete[] cumdiv;
142             }
143         }
144     }
145 
146 private:
147 
148     static int * getHypermatrix(void * pvApiCtx, const int position, const int ndims, const hsize_t * dims);
149 
150     template <typename T>
reorder(const int ndims,const hsize_t * dims,const hsize_t * cumprod,const hsize_t * cumdiv,const T * src,T * dest)151     static void reorder(const int ndims, const hsize_t * dims, const hsize_t * cumprod, const hsize_t * cumdiv, const T * src, T * dest)
152     {
153         if (ndims == 1)
154         {
155             for (int i = 0; i < *dims; i++)
156             {
157                 *dest = src[i];
158                 dest += *cumprod;
159             }
160         }
161         else
162         {
163             for (int i = 0; i < *dims; i++)
164             {
165                 reorder(ndims - 1, dims + 1, cumprod + 1, cumdiv + 1, src, dest);
166                 dest += *cumprod;
167                 src += *cumdiv;
168             }
169         }
170     }
171 };
172 }
173 
174 #endif // __H5DATACONVERTER_HXX__
175