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 __H5BASICDATA_HXX__
17 #define __H5BASICDATA_HXX__
18 
19 #include <string.h>
20 #include "H5Data.hxx"
21 #include "H5Object.hxx"
22 #include "H5DataConverter.hxx"
23 
24 #define __SCILAB_STACK_CREATOR__(U,NAME) static void create(void * pvApiCtx, const int position, const int rows, const int cols, U const* ptr, int * list, const int listPosition) \
25     {                                                                   \
26         SciErr err;                                                     \
27         if (list)                                                       \
28         {                                                               \
29             if (rows == 0 || cols == 0)                                 \
30             {                                                           \
31                 createMatrixOfDoubleInList(pvApiCtx, position, list, listPosition, 0, 0, 0); \
32                 return;                                                 \
33             }                                                           \
34             err = createMatrixOf##NAME##InList(pvApiCtx, position, list, listPosition, rows, cols, ptr); \
35         }                                                               \
36         else                                                            \
37         {                                                               \
38             if (rows == 0 || cols == 0)                                 \
39             {                                                           \
40                 createEmptyMatrix(pvApiCtx, position);                  \
41                 return;                                                 \
42             }                                                           \
43             err = createMatrixOf##NAME(pvApiCtx, position, rows, cols, ptr); \
44         }                                                               \
45         if (err.iErr)                                                   \
46         {                                                               \
47             throw H5Exception(__LINE__, __FILE__, "Cannot allocate memory"); \
48         }                                                               \
49     }
50 
51 #define __SCILAB_STACK_ALLOCATOR__(U,NAME) static void alloc(void * pvApiCtx, const int position, const int rows, const int cols, int * list, const int listPosition, U ** ptr) \
52     {                                                                   \
53         SciErr err;                                                     \
54         if (list)                                                       \
55         {                                                               \
56             err = allocMatrixOf##NAME##InList(pvApiCtx, position, list, listPosition, rows, cols, ptr); \
57         }                                                               \
58         else                                                            \
59         {                                                               \
60             err = allocMatrixOf##NAME(pvApiCtx, position, rows, cols, ptr); \
61         }                                                               \
62         if (err.iErr)                                                   \
63         {                                                               \
64             throw H5Exception(__LINE__, __FILE__, "Cannot allocate memory"); \
65         }                                                               \
66     }
67 
68 #define __SCILAB_ALLOCATORS_CREATORS__(U,NAME) __SCILAB_STACK_CREATOR__(U,NAME) \
69     __SCILAB_STACK_ALLOCATOR__(U,NAME)
70 
71 
72 namespace org_modules_hdf5
73 {
74 template<typename T>
75 class H5BasicData : public H5Data
76 {
77 
78 protected:
79 
80     T * transformedData;
81 
82 public:
83 
H5BasicData(H5Object & _parent,const hsize_t _totalSize,const hsize_t _dataSize,const hsize_t _ndims,const hsize_t * _dims,T * _data,const hsize_t _stride,const size_t _offset,const bool _dataOwner)84     H5BasicData(H5Object & _parent, const hsize_t _totalSize, const hsize_t _dataSize, const hsize_t _ndims, const hsize_t * _dims, T * _data, const hsize_t _stride, const size_t _offset, const bool _dataOwner) : H5Data(_parent, _totalSize, _dataSize, _ndims, _dims, static_cast<void *>(_data), _stride, _offset, _dataOwner), transformedData(0)
85     {
86         //std::cout << totalSize << ", " << stride << ", " << offset << std::endl;
87     }
88 
~H5BasicData()89     virtual ~H5BasicData()
90     {
91         if (transformedData)
92         {
93             delete[] transformedData;
94         }
95     }
96 
printData(std::ostream & os,const unsigned int pos,const unsigned int indentLevel) const97     virtual void printData(std::ostream & os, const unsigned int pos, const unsigned int indentLevel) const
98     {
99         os << static_cast<T *>(getData())[pos];
100     }
101 
copyData(T * dest) const102     virtual void copyData(T * dest) const
103     {
104         if (dest)
105         {
106             if (stride == 0)
107             {
108                 memcpy(static_cast<void *>(dest), data, totalSize * dataSize);
109             }
110             else if (transformedData)
111             {
112                 memcpy(static_cast<void *>(dest), static_cast<void *>(transformedData), totalSize * dataSize);
113             }
114             else
115             {
116                 char * cdata = static_cast<char *>(data) + offset;
117                 if (sizeof(T) == dataSize)
118                 {
119                     for (int i = 0; i < totalSize; i++)
120                     {
121                         dest[i] = *((T *)cdata);
122                         cdata += stride;
123                     }
124                 }
125                 else
126                 {
127                     char * _dest = reinterpret_cast<char *>(dest);
128                     for (int i = 0; i < totalSize; i++)
129                     {
130                         memcpy(_dest, cdata, dataSize);
131                         cdata += stride;
132                         _dest += dataSize;
133                     }
134                 }
135             }
136         }
137         else
138         {
139             throw H5Exception(__LINE__, __FILE__, _("Cannot copy data to an empty pointer"));
140         }
141     }
142 
getData() const143     inline virtual void * getData() const
144     {
145         if (stride == 0)
146         {
147             return data;
148         }
149         else
150         {
151             if (!transformedData)
152             {
153                 char * dest = new char[totalSize * dataSize];
154                 copyData(reinterpret_cast<T *>(dest));
155                 const_cast<H5BasicData *>(this)->transformedData = reinterpret_cast<T *>(dest);
156             }
157 
158             return static_cast<void *>(transformedData);
159         }
160     }
161 
toScilab(void * pvApiCtx,const int lhsPosition,int * parentList=0,const int listPosition=0,const bool flip=true) const162     virtual void toScilab(void * pvApiCtx, const int lhsPosition, int * parentList = 0, const int listPosition = 0, const bool flip = true) const
163     {
164         T * newData = 0;
165         hsize_t _ndims = ndims;
166         hsize_t _totalSize = totalSize;
167         hsize_t * _dims = const_cast<hsize_t *>(dims);
168 
169         if (_ndims == 0)
170         {
171             create(pvApiCtx, lhsPosition, 1, 1, static_cast<T *>(getData()), parentList, listPosition);
172         }
173         else if (_ndims == 1)
174         {
175             alloc(pvApiCtx, lhsPosition, 1, (int)*_dims, parentList, listPosition, &newData);
176             copyData(newData);
177         }
178         else
179         {
180             if (_ndims == 2)
181             {
182                 if (flip)
183                 {
184                     alloc(pvApiCtx, lhsPosition, (int)_dims[1], (int)_dims[0], parentList, listPosition, &newData);
185                 }
186                 else
187                 {
188                     alloc(pvApiCtx, lhsPosition, (int)_dims[0], (int)_dims[1], parentList, listPosition, &newData);
189                 }
190 
191                 H5DataConverter::C2FHypermatrix(2, _dims, 0, static_cast<T *>(getData()), newData, flip);
192             }
193             else
194             {
195                 int* pNewDataVar = NULL;
196                 int i = 0;
197                 int indims = (int)_ndims;
198                 int* piDimsArray = new int[indims];
199 
200                 alloc(pvApiCtx, lhsPosition, (int)_totalSize, 1, parentList, listPosition, &newData);
201                 if (parentList)
202                 {
203                     getListItemAddress(pvApiCtx, parentList, listPosition, &pNewDataVar);
204                 }
205                 else
206                 {
207                     getVarAddressFromPosition(pvApiCtx, lhsPosition, &pNewDataVar);
208                 }
209 
210                 if (flip)
211                 {
212                     for (i = 0; i < indims; i++)
213                     {
214                         piDimsArray[indims - 1 - i] = (int)_dims[i];
215                     }
216                 }
217                 else
218                 {
219                     for (i = 0; i < indims; i++)
220                     {
221                         piDimsArray[i] = (int)_dims[i];
222                     }
223                 }
224                 reshapeArray(pvApiCtx, pNewDataVar, piDimsArray, indims);
225                 delete[] piDimsArray;
226 
227                 H5DataConverter::C2FHypermatrix(indims, _dims, _totalSize, static_cast<T *>(getData()), newData, flip);
228             }
229         }
230     }
231 
dump(std::map<haddr_t,std::string> & alreadyVisited,const unsigned int indentLevel) const232     virtual std::string dump(std::map<haddr_t, std::string> & alreadyVisited, const unsigned int indentLevel) const
233     {
234         return H5DataConverter::dump(alreadyVisited, indentLevel, (int)ndims, dims, *this);
235     }
236 
putStringVectorOnStack(std::vector<std::string> & strs,const int rows,const int cols,const int pos,void * pvApiCtx)237     static void putStringVectorOnStack(std::vector<std::string> & strs, const int rows, const int cols, const int pos, void * pvApiCtx)
238     {
239         if (rows * cols != strs.size())
240         {
241             throw H5Exception(__LINE__, __FILE__, _("Wrong dimensions."));
242         }
243 
244         if (strs.size() == 0)
245         {
246             create(pvApiCtx, pos, 0, 0, "", 0, 0);
247         }
248         else
249         {
250             std::vector<const char *> _strs;
251             _strs.reserve(strs.size());
252             for (unsigned int i = 0; i < strs.size(); i++)
253             {
254                 _strs.push_back(strs[i].c_str());
255             }
256             create(pvApiCtx, pos, rows, cols, const_cast<char **>(&(_strs[0])), 0, 0);
257         }
258     }
259 
__SCILAB_ALLOCATORS_CREATORS__(double,Double)260     __SCILAB_ALLOCATORS_CREATORS__(double, Double)
261     __SCILAB_ALLOCATORS_CREATORS__(char, Integer8)
262     __SCILAB_ALLOCATORS_CREATORS__(unsigned char, UnsignedInteger8)
263     __SCILAB_ALLOCATORS_CREATORS__(short, Integer16)
264     __SCILAB_ALLOCATORS_CREATORS__(unsigned short, UnsignedInteger16)
265     __SCILAB_ALLOCATORS_CREATORS__(int, Integer32)
266     __SCILAB_ALLOCATORS_CREATORS__(unsigned int, UnsignedInteger32)
267 
268 #ifdef  __SCILAB_INT64__
269     __SCILAB_ALLOCATORS_CREATORS__(long long, Integer64)
270     __SCILAB_ALLOCATORS_CREATORS__(unsigned long long, UnsignedInteger64)
271 #endif
272 
273     __SCILAB_STACK_CREATOR__(char *, String)
274     static void alloc(void * pvApiCtx, const int position, const int rows, const int cols, int * list, const int listPosition, char*** ptr) {}
275 };
276 }
277 
278 
279 #undef __SCILAB_STACK_CREATOR__
280 #undef __SCILAB_STACK_ALLOCATOR__
281 #undef __SCILAB_LIST_CREATOR__
282 #undef __SCILAB_LIST_ALLOCATOR__
283 #undef __SCILAB_ALLOCATORS_CREATORS__
284 
285 #endif // __H5BASICDATA_HXX__
286