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 #include "H5StringData.hxx"
17 
18 namespace org_modules_hdf5
19 {
20 
H5StringData(H5Object & _parent,const hsize_t _totalSize,const hsize_t _stringSize,const hsize_t _ndims,const hsize_t * _dims,char * _data,const hsize_t _stride,const size_t _offset,const bool _dataOwner)21 H5StringData::H5StringData(H5Object & _parent, const hsize_t _totalSize, const hsize_t _stringSize, const hsize_t _ndims, const hsize_t * _dims, char * _data, const hsize_t _stride, const size_t _offset, const bool _dataOwner) : H5Data(_parent, _totalSize, _stringSize, _ndims, _dims, _data, _stride == 0 ? _stringSize : _stride, _offset, _dataOwner)
22 {
23     char * __data = static_cast<char *>(_data);
24     transformedData = new char*[totalSize];
25 
26     if (stride == 0)
27     {
28         *transformedData = __data;
29         for (unsigned int i = 1; i < (unsigned int)totalSize; i++)
30         {
31             transformedData[i] = transformedData[i - 1] + dataSize;
32         }
33     }
34     else
35     {
36         for (unsigned int i = 0; i < (unsigned int)totalSize; i++)
37         {
38             transformedData[i] = __data + offset;
39             __data += stride;
40         }
41     }
42 }
43 
H5StringData(H5Object & _parent,const hsize_t _totalSize,const hsize_t _stringSize,const hsize_t _ndims,const hsize_t * _dims,char ** _data,const hsize_t _stride,const size_t _offset,const bool _dataOwner)44 H5StringData::H5StringData(H5Object & _parent, const hsize_t _totalSize, const hsize_t _stringSize, const hsize_t _ndims, const hsize_t * _dims, char ** _data, const hsize_t _stride, const size_t _offset, const bool _dataOwner) : H5Data(_parent, _totalSize, _stringSize, _ndims, _dims, _data, _stride == 0 ? _stringSize : _stride, _offset, _dataOwner), transformedData(0)
45 {
46 
47 }
48 
~H5StringData()49 H5StringData::~H5StringData()
50 {
51 
52     if (transformedData)
53     {
54         delete[] transformedData;
55     }
56     else
57     {
58         char ** _data = reinterpret_cast<char **>(getData());
59         hid_t space = H5Screate_simple(1, &totalSize, 0);
60         hid_t type = H5Tcopy(H5T_C_S1);
61         H5Tset_size(type, H5T_VARIABLE);
62         H5Tset_strpad(type, H5T_STR_NULLTERM);
63 
64         herr_t err = H5Dvlen_reclaim(type, space, H5P_DEFAULT, _data);
65         if (err < 0)
66         {
67             throw H5Exception(__LINE__, __FILE__, _("Cannot free the memory associated with String data"));
68         }
69 
70         H5Tclose(type);
71         H5Sclose(space);
72     }
73 }
74 
getData() const75 void * H5StringData::getData() const
76 {
77     if (transformedData)
78     {
79         return transformedData;
80     }
81     else
82     {
83         return H5Data::getData();
84     }
85 }
86 
printData(std::ostream & os,const unsigned int pos,const unsigned int indentLevel) const87 void H5StringData::printData(std::ostream & os, const unsigned int pos, const unsigned int indentLevel) const
88 {
89     char * str = static_cast<char **>(getData())[pos];
90     if (str)
91     {
92         os << "\"" << str << "\"";
93     }
94     else
95     {
96         os << "NULL";
97     }
98 }
99 
toScilab(void * pvApiCtx,const int lhsPosition,int * parentList,const int listPosition,const bool flip) const100 void H5StringData::toScilab(void * pvApiCtx, const int lhsPosition, int * parentList, const int listPosition, const bool flip) const
101 {
102     static char EMPTY[] = { '\0' };
103 
104     char ** _tdata = 0;
105     char ** _data = static_cast<char **>(getData());
106 
107     if (!transformedData)
108     {
109         // It is possible to have a nil pointer (Scilab doesn't like that)
110         // so we replace nil ptr by an empty string...
111 
112         _tdata = new char *[totalSize];
113         for (hsize_t i = 0; i < totalSize; i++)
114         {
115             if (_data[i])
116             {
117                 _tdata[i] = _data[i];
118             }
119             else
120             {
121                 _tdata[i] = static_cast<char *>(EMPTY);
122             }
123         }
124         _data = _tdata;
125     }
126 
127     std::cout << ndims << std::endl;
128 
129     if (ndims == 0)
130     {
131         H5BasicData<char *>::create(pvApiCtx, lhsPosition, 1, 1, _data, parentList, listPosition);
132     }
133     else if (ndims == 1)
134     {
135         H5BasicData<char *>::create(pvApiCtx, lhsPosition, 1, (int)*dims, _data, parentList, listPosition);
136     }
137     else
138     {
139         char ** newData = new char *[totalSize];
140         if (ndims == 2)
141         {
142             H5DataConverter::C2FHypermatrix(2, dims, 0, _data, newData, flip);
143             if (flip)
144             {
145                 H5BasicData<char *>::create(pvApiCtx, lhsPosition, (int)dims[1], (int)dims[0], newData, parentList, listPosition);
146             }
147             else
148             {
149                 H5BasicData<char *>::create(pvApiCtx, lhsPosition, (int)dims[0], (int)dims[1], newData, parentList, listPosition);
150             }
151         }
152         else
153         {
154             int * list = getHypermatrix(pvApiCtx, lhsPosition, parentList, listPosition, flip);
155             H5DataConverter::C2FHypermatrix((int)ndims, dims, totalSize, _data, newData, flip);
156             H5BasicData<char *>::create(pvApiCtx, lhsPosition, (int)totalSize, 1, newData, list, 3);
157         }
158         delete[] newData;
159     }
160 
161     if (_tdata)
162     {
163         delete[] _tdata;
164     }
165 }
166 
dump(std::map<haddr_t,std::string> & alreadyVisited,const unsigned int indentLevel) const167 std::string H5StringData::dump(std::map<haddr_t, std::string> & alreadyVisited, const unsigned int indentLevel) const
168 {
169     return H5DataConverter::dump(alreadyVisited, indentLevel, (int)ndims, dims, *this);
170 }
171 }
172