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 "H5Options.hxx"
17 #include "H5CompoundData.hxx"
18 #include "H5DataFactory.hxx"
19
20 namespace org_modules_hdf5
21 {
22
H5CompoundData(H5Object & _parent,const hsize_t _totalSize,const hsize_t _dataSize,const hsize_t _ndims,const hsize_t * _dims,char * _data,hid_t compoundType,const hsize_t _stride,const size_t _offset,const bool _dataOwner)23 H5CompoundData::H5CompoundData(H5Object & _parent, const hsize_t _totalSize, const hsize_t _dataSize, const hsize_t _ndims, const hsize_t * _dims, char * _data, hid_t compoundType, const hsize_t _stride, const size_t _offset, const bool _dataOwner) : H5BasicData<char>(_parent, _totalSize, _dataSize, _ndims, _dims, _data, _stride, _offset, _dataOwner), type(compoundType), cumprod(H5Object::getCumProd(_ndims, dims))
24 {
25 nfields = (unsigned int)H5Tget_nmembers(compoundType);
26 infos = new std::map<std::string, FieldInfo *>();
27 fieldinfos = new FieldInfo *[nfields];
28 for (unsigned int i = 0; i < nfields; i++)
29 {
30 hid_t mtype = H5Tget_member_type(compoundType, i);
31 hsize_t size = H5Tget_size(mtype);
32 char * mname = H5Tget_member_name(compoundType, i);
33 std::string name(mname);
34
35 //free crash: it will be fix with hdf5 libs >= 1.8.16 with new function h5free_memory
36 //h5free_memory(mname);
37
38 size_t offs = H5Tget_member_offset(compoundType, i);
39 FieldInfo * info = 0;
40 if (H5Tget_class(type) == H5T_STRING && !H5Tis_variable_str(type))
41 {
42 // We have a C-string so it is null terminated
43 size++;
44 }
45
46 info = new FieldInfo(mtype, size, offs, name);
47 (*infos)[name] = info;
48 fieldinfos[i] = info;
49 }
50 }
51
~H5CompoundData()52 H5CompoundData::~H5CompoundData()
53 {
54 infos->erase(infos->begin(), infos->end());
55 delete infos;
56 delete[] fieldinfos;
57 delete[] cumprod;
58 H5Tclose(type);
59 }
60
toScilab(void * pvApiCtx,const int lhsPosition,int * parentList,const int listPosition,const bool flip) const61 void H5CompoundData::toScilab(void * pvApiCtx, const int lhsPosition, int * parentList, const int listPosition, const bool flip) const
62 {
63 H5Object::toScilab(pvApiCtx, lhsPosition, parentList, listPosition, flip);
64 }
65
isCompound() const66 bool H5CompoundData::isCompound() const
67 {
68 return true;
69 }
70
getAccessibleAttribute(const std::string & _name,const int pos,void * pvApiCtx) const71 void H5CompoundData::getAccessibleAttribute(const std::string & _name, const int pos, void * pvApiCtx) const
72 {
73 H5Data & data = getData(_name);
74 data.toScilab(pvApiCtx, pos, 0, 0, H5Options::isReadFlip());
75
76 if (data.mustDelete())
77 {
78 delete &data;
79 }
80 }
81
getData(const std::string fieldname) const82 H5Data & H5CompoundData::getData(const std::string fieldname) const
83 {
84 std::map<std::string, FieldInfo *>::const_iterator it = infos->find(fieldname);
85
86 if (it != infos->end())
87 {
88 return H5DataFactory::getObjectData(*const_cast<H5CompoundData *>(this), totalSize, it->second->size, it->second->type, ndims, dims, data, stride ? stride : dataSize, offset + it->second->offset, false);
89 }
90
91 throw H5Exception(__LINE__, __FILE__, _("Invalid field name: %s"), fieldname.c_str());
92 }
93
getData(const unsigned int size,const unsigned int * index) const94 H5Object & H5CompoundData::getData(const unsigned int size, const unsigned int * index) const
95 {
96 unsigned int pos = 0;
97 unsigned int cumprod = 1;
98 hsize_t * _dims = 0;
99
100 for (unsigned int i = 0; i < size; i++)
101 {
102 pos += cumprod * index[i];
103 }
104
105 if (pos >= totalSize)
106 {
107 throw H5Exception(__LINE__, __FILE__, _("Invalid index.\n"));
108 }
109
110 _dims = new hsize_t[1];
111 _dims[0] = 1;
112
113 return *new H5CompoundData(*const_cast<H5CompoundData *>(this), 1, dataSize, 1, _dims, static_cast<char *>(data) + offset + pos * (dataSize + stride), type, 0, 0, false);
114 }
115
getFieldNames(const int position,void * pvApiCtx)116 void H5CompoundData::getFieldNames(const int position, void * pvApiCtx)
117 {
118 std::vector<std::string> names;
119 names.reserve(nfields);
120
121 for (unsigned int i = 0; i < nfields; i++)
122 {
123 names.push_back(fieldinfos[i]->name);
124 }
125 H5BasicData<char>::putStringVectorOnStack(names, (int)names.size(), 1, position, pvApiCtx);
126 }
127
toString(const unsigned int indentLevel) const128 std::string H5CompoundData::toString(const unsigned int indentLevel) const
129 {
130 std::ostringstream os;
131 std::string indentString = H5Object::getIndentString(indentLevel + 1);
132
133 os << H5Object::getIndentString(indentLevel) << "HDF5 Compound data" << std::endl
134 << indentString << _("Dimensions") << ": [";
135
136 if (ndims == 0)
137 {
138 os << "1 x 1]";
139 }
140 else if (ndims == 1)
141 {
142 os << "1 x " << dims[0] << "]";
143 }
144 else
145 {
146 for (unsigned int i = 0; i < ndims - 1; i++)
147 {
148 os << dims[i] << " x ";
149 }
150 os << dims[ndims - 1] << "]" << std::endl;
151 }
152
153 os << indentString << _("Fields Names") << ": [";
154 for (unsigned int i = 0; i < nfields - 1; i++)
155 {
156 os << fieldinfos[i]->name << ", ";
157 }
158 os << fieldinfos[nfields - 1]->name << "]";
159
160 return os.str();
161 }
162
dump(std::map<haddr_t,std::string> & alreadyVisited,const unsigned int indentLevel) const163 std::string H5CompoundData::dump(std::map<haddr_t, std::string> & alreadyVisited, const unsigned int indentLevel) const
164 {
165 return H5DataConverter::dump(alreadyVisited, indentLevel, (int)ndims, dims, *this, false);
166 }
167
printData(std::ostream & os,const unsigned int pos,const unsigned int indentLevel) const168 void H5CompoundData::printData(std::ostream & os, const unsigned int pos, const unsigned int indentLevel) const
169 {
170 os << "{" << std::endl;
171 std::string indent = H5Object::getIndentString(indentLevel + 2);
172
173 for (unsigned int i = 0; i < nfields; i++)
174 {
175 H5Data & hdata = H5DataFactory::getObjectData(*const_cast<H5CompoundData *>(this), totalSize, fieldinfos[i]->size, fieldinfos[i]->type, ndims, dims, data, stride ? stride : dataSize, offset + fieldinfos[i]->offset, false);
176 os << indent;
177 hdata.printData(os, pos, indentLevel + 2);
178
179 if (i != nfields - 1)
180 {
181 os << ", " << std::endl;
182 }
183
184 delete &hdata;
185 }
186
187 os << std::endl << H5Object::getIndentString(indentLevel + 1) << "}";
188 }
189 }
190