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 "H5Attribute.hxx"
18 #include "H5DataFactory.hxx"
19
20 namespace org_modules_hdf5
21 {
22
H5Attribute(H5Object & _parent,const std::string & _name)23 H5Attribute::H5Attribute(H5Object & _parent, const std::string & _name) : H5Object(_parent, _name)
24 {
25 if (H5Aexists(getParent().getH5Id(), name.c_str()) <= 0)
26 {
27 throw H5Exception(__LINE__, __FILE__, _("Cannot open attribute: %s"), name.c_str());
28 }
29
30 attr = H5Aopen(getParent().getH5Id(), name.c_str(), H5P_DEFAULT);
31 if (attr < 0)
32 {
33 throw H5Exception(__LINE__, __FILE__, _("Cannot open attribute: %s"), name.c_str());
34 }
35 }
36
H5Attribute(H5Object & _parent,hid_t _attr,const std::string & _name)37 H5Attribute::H5Attribute(H5Object & _parent, hid_t _attr, const std::string & _name) : H5Object(_parent, _name), attr(_attr)
38 {
39
40 }
41
~H5Attribute()42 H5Attribute::~H5Attribute()
43 {
44 if (attr >= 0)
45 {
46 H5Aclose(attr);
47 }
48 }
49
getData()50 H5Data & H5Attribute::getData()
51 {
52 return H5DataFactory::getData(*this, attr, 0, 0, true);
53 }
54
getDataType()55 H5Type & H5Attribute::getDataType()
56 {
57 hid_t type = H5Aget_type(attr);
58 if (type < 0)
59 {
60 throw H5Exception(__LINE__, __FILE__, _("Cannot get the attribute type"));
61 }
62
63 return *new H5Type(*this, type);
64 }
65
getSpace()66 H5Dataspace & H5Attribute::getSpace()
67 {
68 hid_t space = H5Aget_space(attr);
69 if (space < 0)
70 {
71 throw H5Exception(__LINE__, __FILE__, _("Cannot get the attribute dataspace"));
72 }
73
74 return *new H5Dataspace(*this, space);
75 }
76
getAccessibleAttribute(const std::string & _name,const int pos,void * pvApiCtx) const77 void H5Attribute::getAccessibleAttribute(const std::string & _name, const int pos, void * pvApiCtx) const
78 {
79 std::string lower(_name);
80 std::transform(_name.begin(), _name.end(), lower.begin(), tolower);
81
82 if (lower == "type")
83 {
84 const H5Type & type = const_cast<H5Attribute *>(this)->getDataType();
85 type.createOnScilabStack(pos, pvApiCtx);
86
87 return;
88 }
89 else if (lower == "dataspace")
90 {
91 const H5Dataspace & space = const_cast<H5Attribute *>(this)->getSpace();
92 space.createOnScilabStack(pos, pvApiCtx);
93
94 return;
95 }
96 else if (lower == "data")
97 {
98 const H5Data & data = const_cast<H5Attribute *>(this)->getData();
99 data.toScilab(pvApiCtx, pos, 0, 0, H5Options::isReadFlip());
100
101 delete &data;
102
103 return;
104 }
105
106 H5Object::getAccessibleAttribute(_name, pos, pvApiCtx);
107 }
108
dump(std::map<haddr_t,std::string> & alreadyVisited,const unsigned int indentLevel) const109 std::string H5Attribute::dump(std::map<haddr_t, std::string> & alreadyVisited, const unsigned int indentLevel) const
110 {
111 std::ostringstream os;
112 const H5Type & type = const_cast<H5Attribute *>(this)->getDataType();
113 const H5Dataspace & space = const_cast<H5Attribute *>(this)->getSpace();
114 H5Data * data = 0;
115
116 try
117 {
118 data = &const_cast<H5Attribute *>(this)->getData();
119 }
120 catch (const H5Exception & /*e*/)
121 {
122
123 }
124
125 os << H5Object::getIndentString(indentLevel) << "ATTRIBUTE \"" << getName() << "\" {" << std::endl
126 << type.dump(alreadyVisited, indentLevel + 1)
127 << space.dump(alreadyVisited, indentLevel + 1);
128
129 if (data)
130 {
131 os << data->dump(alreadyVisited, indentLevel + 1);
132 }
133 else
134 {
135 os << H5Object::getIndentString(indentLevel + 1) << _("Error in retrieving data.") << std::endl;
136 }
137
138 os << H5Object::getIndentString(indentLevel) << "}" << std::endl;
139
140 delete &type;
141 delete &space;
142 if (data)
143 {
144 delete data;
145 }
146
147 return os.str();
148 }
149
toString(const unsigned int indentLevel) const150 std::string H5Attribute::toString(const unsigned int indentLevel) const
151 {
152 std::ostringstream os;
153 const std::string indentString = H5Object::getIndentString(indentLevel + 1);
154 const H5Type & type = const_cast<H5Attribute *>(this)->getDataType();
155 const H5Dataspace & space = const_cast<H5Attribute *>(this)->getSpace();
156
157 os << H5Object::getIndentString(indentLevel) << "HDF5 Attribute" << std::endl
158 << indentString << "Filename" << ": " << getFile().getFileName() << std::endl
159 << indentString << "Name" << ": " << getName() << std::endl
160 << indentString << "Parent path" << ": " << getParent().getCompletePath() << std::endl
161 << indentString << "Type" << ": " << type.getTypeName() << std::endl
162 << indentString << "Dataspace" << ": " << space.getTypeName() << std::endl
163 << indentString << "Data" << ": " << space.getStringDims() << std::endl;
164
165 delete &type;
166 delete &space;
167
168 return os.str();
169 }
170
copy(H5Object & parent,const std::string & name)171 void H5Attribute::copy(H5Object & parent, const std::string & name)
172 {
173 H5Attribute::copy(this->getH5Id(), parent.getH5Id(), name);
174 }
175
create(H5Object & loc,const std::string & name,const hid_t type,const hid_t targettype,const hid_t srcspace,const hid_t targetspace,void * data,const bool chunked)176 hid_t H5Attribute::create(H5Object & loc, const std::string & name, const hid_t type, const hid_t targettype, const hid_t srcspace, const hid_t targetspace, void * data, const bool chunked)
177 {
178 return create(loc.getH5Id(), name, type, targettype, srcspace, targetspace, data);
179 }
180
create(const hid_t loc,const std::string & name,const hid_t type,const hid_t targettype,const hid_t srcspace,const hid_t targetspace,void * data)181 hid_t H5Attribute::create(const hid_t loc, const std::string & name, const hid_t type, const hid_t targettype, const hid_t srcspace, const hid_t targetspace, void * data)
182 {
183 herr_t err;
184 if (H5Aexists(loc, name.c_str()) > 0)
185 {
186 throw H5Exception(__LINE__, __FILE__, _("Attribute %s already exists."), name.c_str());
187 }
188
189 hid_t attr = H5Acreate(loc, name.c_str(), targettype, targetspace == -1 ? srcspace : targetspace, H5P_DEFAULT, H5P_DEFAULT);
190 if (attr < 0)
191 {
192 throw H5Exception(__LINE__, __FILE__, _("Cannot create a new attribute."));
193 }
194
195 err = H5Awrite(attr, type, data);
196 if (err < 0)
197 {
198 H5Aclose(attr);
199 throw H5Exception(__LINE__, __FILE__, _("Cannot write data in the attribute."));
200 }
201
202 return attr;
203 }
204
copy(const hid_t src,const hid_t dest,const std::string & name)205 void H5Attribute::copy(const hid_t src, const hid_t dest, const std::string & name)
206 {
207 hid_t type, stype;
208 hid_t space, sspace;
209 char * data = 0;
210 hsize_t size;
211 hsize_t * dims = 0;
212 hsize_t ndims;
213
214 sspace = H5Aget_space(src);
215 if (sspace < 0)
216 {
217 throw H5Exception(__LINE__, __FILE__, _("Cannot copy the attribute"));
218 }
219 space = H5Scopy(sspace);
220 H5Sclose(sspace);
221
222 stype = H5Aget_type(src);
223 if (stype < 0)
224 {
225 H5Sclose(space);
226 throw H5Exception(__LINE__, __FILE__, _("Cannot copy the attribute"));
227 }
228 type = H5Tcopy(stype);
229 H5Tclose(stype);
230
231 size = H5Tget_size(type);
232 dims = new hsize_t[__SCILAB_HDF5_MAX_DIMS__];
233 ndims = H5Sget_simple_extent_dims(space, dims, 0);
234 for (unsigned int i = 0; i < ndims; i++)
235 {
236 size *= dims[i];
237 }
238
239 data = new char[size];
240 if (H5Aread(src, type, data) < 0)
241 {
242 H5Sclose(space);
243 H5Tclose(type);
244 delete[] dims;
245 delete[] data;
246
247 throw H5Exception(__LINE__, __FILE__, _("Cannot read attribute data."));
248 }
249
250 try
251 {
252 hid_t attr = create(dest, name, type, type, space, space, data);
253 H5Aclose(attr);
254 H5Sclose(space);
255 H5Tclose(type);
256 delete[] dims;
257 delete[] data;
258 }
259 catch (const H5Exception & /*e*/)
260 {
261 H5Sclose(space);
262 H5Tclose(type);
263 delete[] dims;
264 delete[] data;
265 throw;
266 }
267 }
268
269 }
270