52b0883d40090095b597082da35aae12b1fe6c2a
[scilab.git] / scilab / modules / hdf5 / src / cpp / H5Dataset.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include "H5Dataset.hxx"
14 #include "H5DataFactory.hxx"
15 #include "H5Attribute.hxx"
16 #include "H5HardLink.hxx"
17
18 namespace org_modules_hdf5
19 {
20
21 void H5Dataset::init()
22 {
23     dataset = H5Dopen2(getParent().getH5Id(), name.c_str(), H5P_DEFAULT);
24     if (dataset < 0)
25     {
26         throw H5Exception(__LINE__, __FILE__, _("Cannot open the given dataset %s."), name.c_str());
27     }
28 }
29
30 H5Dataset::H5Dataset(H5Object & _parent, const char * _name) : H5Object(_parent), name(std::string(_name)), dataset((hid_t) - 1)
31 {
32     init();
33 }
34
35 H5Dataset::H5Dataset(H5Object & _parent, const std::string & _name) : H5Object(_parent), name(_name), dataset((hid_t) - 1)
36 {
37     init();
38 }
39
40 H5Dataset::H5Dataset(H5Object & _parent, hid_t _dataset, const char * _name) : H5Object(_parent), dataset(_dataset), name(std::string(_name))
41 {
42
43 }
44
45 H5Dataset::H5Dataset(H5Object & _parent, hid_t _dataset, const std::string & _name) : H5Object(_parent), dataset(_dataset), name(_name)
46 {
47
48 }
49
50 H5Dataset::~H5Dataset()
51 {
52     if (dataset >= 0)
53     {
54         H5Dclose(dataset);
55     }
56 }
57
58 H5Data & H5Dataset::getData()
59 {
60     return H5DataFactory::getData(*this, dataset, false);
61 }
62
63 H5Dataspace & H5Dataset::getSpace()
64 {
65     hid_t space = H5Dget_space(dataset);
66     if (space < 0)
67     {
68         throw H5Exception(__LINE__, __FILE__, _("Cannot get the dataspace associated with dataset named %s."), name.c_str());
69     }
70
71     return *new H5Dataspace(*this, space);
72 }
73
74 H5Type & H5Dataset::getDataType()
75 {
76     hid_t type = H5Dget_type(dataset);
77     if (type < 0)
78     {
79         throw H5Exception(__LINE__, __FILE__, _("Cannot get the dataspace associated with dataset named %s."), name.c_str());
80     }
81
82     return *new H5Type(*this, type);
83 }
84
85 H5Dataset::H5Layout & H5Dataset::getLayout()
86 {
87     hid_t plist = H5Dget_create_plist(dataset);
88     H5D_layout_t layout = H5Pget_layout(plist);
89     H5Dataset::H5Layout * obj = 0;
90
91     switch (layout)
92     {
93         case H5D_COMPACT:
94             obj = new H5Dataset::H5CompactLayout(*this);
95             break;
96         case H5D_CONTIGUOUS:
97             obj = new H5Dataset::H5ContiguousLayout(*this);
98             break;
99         case H5D_CHUNKED:
100             obj = new H5Dataset::H5ChunkedLayout(*this);
101             break;
102         default:
103             H5Pclose(plist);
104             throw H5Exception(__LINE__, __FILE__, _("Invalid layout"));
105     }
106
107     H5Pclose(plist);
108
109     return *obj;
110 }
111
112 void H5Dataset::getAccessibleAttribute(const std::string & _name, const int pos, void * pvApiCtx) const
113 {
114     SciErr err;
115     std::string lower(_name);
116
117     try
118     {
119         H5Attribute * attr = new H5Attribute(*const_cast<H5Dataset *>(this), _name);
120         attr->createOnScilabStack(pos, pvApiCtx);
121
122         return;
123     }
124     catch (H5Exception & e) { }
125
126     std::transform(_name.begin(), _name.end(), lower.begin(), tolower);
127
128     if (lower == "attributes")
129     {
130         const H5AttributesList & attrs = const_cast<H5Dataset *>(this)->getAttributes();
131         attrs.createOnScilabStack(pos, pvApiCtx);
132
133         return;
134     }
135     else if (lower == "type")
136     {
137         const H5Type & type = const_cast<H5Dataset *>(this)->getDataType();
138         type.createOnScilabStack(pos, pvApiCtx);
139
140         return;
141     }
142     else if (lower == "dataspace")
143     {
144         const H5Dataspace & space = const_cast<H5Dataset *>(this)->getSpace();
145         space.createOnScilabStack(pos, pvApiCtx);
146
147         return;
148     }
149     else if (lower == "data")
150     {
151         const H5Data & data = const_cast<H5Dataset *>(this)->getData();
152         data.toScilab(pvApiCtx, pos);
153
154         delete &data;
155
156         return;
157     }
158     else if (lower == "layout")
159     {
160         const H5Dataset::H5Layout & layout = const_cast<H5Dataset *>(this)->getLayout();
161         layout.createOnScilabStack(pos, pvApiCtx);
162
163         return;
164     }
165
166     H5Object::getAccessibleAttribute(_name, pos, pvApiCtx);
167 }
168
169 std::string H5Dataset::dump(std::map<haddr_t, std::string> & alreadyVisited, const unsigned int indentLevel) const
170 {
171     std::ostringstream os;
172     haddr_t addr = this->getAddr();
173     std::map<haddr_t, std::string>::iterator it = alreadyVisited.find(addr);
174     if (it != alreadyVisited.end())
175     {
176         os << H5Object::getIndentString(indentLevel) << "DATASET \"" << getName() << "\" {" << std::endl
177            << H5Object::getIndentString(indentLevel + 1) << "HARDLINK \"" << it->second << "\"" << std::endl
178            << H5Object::getIndentString(indentLevel) << "}" << std::endl;
179
180         return os.str();
181     }
182     else
183     {
184         alreadyVisited.insert(std::pair<haddr_t, std::string>(addr, getCompletePath()));
185     }
186
187     const H5Type & type = const_cast<H5Dataset *>(this)->getDataType();
188     const H5Dataspace & space = const_cast<H5Dataset *>(this)->getSpace();
189     const H5AttributesList & attrs = const_cast<H5Dataset *>(this)->getAttributes();
190     const H5Data & data = const_cast<H5Dataset *>(this)->getData();
191     const H5Dataset::H5Layout & layout = const_cast<H5Dataset *>(this)->getLayout();
192
193     os << H5Object::getIndentString(indentLevel) << "DATASET \"" << getName() << "\" {" << std::endl
194        << type.dump(alreadyVisited, indentLevel + 1)
195        << space.dump(alreadyVisited, indentLevel + 1)
196        << layout.dump(alreadyVisited, indentLevel + 1)
197        << data.dump(alreadyVisited, indentLevel + 1)
198        << attrs.dump(alreadyVisited, indentLevel + 1)
199        << H5Object::getIndentString(indentLevel) << "}" << std::endl;
200
201     delete &type;
202     delete &space;
203     delete &data;
204     delete &attrs;
205     delete &layout;
206
207     return os.str();
208 }
209
210 void H5Dataset::printLsInfo(std::ostringstream & os) const
211 {
212     const H5Dataspace & space = const_cast<H5Dataset *>(this)->getSpace();
213     std::vector<unsigned int> dims = space.getDims();
214     std::string str(getName());
215     H5Object::getResizedString(str);
216
217     os << str << "Dataset {";
218
219     if (dims.size() == 0)
220     {
221         os << "}";
222     }
223     else
224     {
225         for (unsigned int i = 0; i < dims.size() - 1; i++)
226         {
227             os << dims[i] << ", ";
228         }
229         os << dims[dims.size() - 1] << "}";
230     }
231
232     delete &space;
233
234     os << std::endl;
235 }
236
237 std::string H5Dataset::ls() const
238 {
239     std::ostringstream os;
240     printLsInfo(os);
241
242     return os.str();
243 }
244
245 std::string H5Dataset::toString(const unsigned int indentLevel) const
246 {
247     std::ostringstream os;
248     std::string indentString = H5Object::getIndentString(indentLevel + 1);
249     const H5Type & type = const_cast<H5Dataset *>(this)->getDataType();
250     const H5AttributesList & attrs = const_cast<H5Dataset *>(this)->getAttributes();
251
252     os << H5Object::getIndentString(indentLevel) << "HDF5 Dataset" << std::endl
253        << indentString << _("Filename") << ": " << getParent().getFile().getFileName() << std::endl
254        << indentString << _("Name") << ": " << getName() << std::endl
255        << indentString << _("Path") << ": " << getCompletePath() << std::endl
256        << indentString << _("Elements type") << ": " << type.getTypeName() << std::endl
257        << indentString << _("Attributes") << ": [1 x " << attrs.getSize() << "]";
258
259     delete &type;
260     delete &attrs;
261
262     return os.str();
263 }
264
265 hid_t H5Dataset::create(H5Object & loc, const std::string & name, hid_t type, hid_t targettype, hid_t space, void * data)
266 {
267     herr_t err;
268     hid_t dataset = H5Dcreate2(loc.getH5Id(), name.c_str(), targettype, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
269     if (dataset < 0)
270     {
271         throw H5Exception(__LINE__, __FILE__, _("Cannot create a new dataset."));
272     }
273
274     err = H5Dwrite(dataset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
275     if (err < 0)
276     {
277         throw H5Exception(__LINE__, __FILE__, _("Cannot write data in the dataset."));
278     }
279
280     return dataset;
281 }
282 }