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 __HDF5SCILAB_HXX__ 17 #define __HDF5SCILAB_HXX__ 18 19 #include <vector> 20 #include <map> 21 22 #include "H5Options.hxx" 23 #include "H5Object.hxx" 24 #include "H5File.hxx" 25 #include "H5Group.hxx" 26 #include "H5Dataset.hxx" 27 #include "H5Dataspace.hxx" 28 #include "H5Attribute.hxx" 29 #include "H5BasicData.hxx" 30 #include "H5Data.hxx" 31 #include "H5VariableScope.hxx" 32 33 extern "C" 34 { 35 #include "doublecomplex.h" 36 #include "api_scilab.h" 37 #include "Scierror.h" 38 #include "HDF5Objects.h" 39 #include "sciprint.h" 40 #include "localization.h" 41 } 42 43 namespace org_modules_hdf5 44 { 45 46 class HDF5Scilab 47 { 48 49 public: 50 51 enum H5ObjectType 52 { 53 H5FILE, 54 H5GROUP, 55 H5DATASET, 56 H5ATTRIBUTE, 57 H5SPACE, 58 H5TYPE, 59 H5REFERENCE, 60 H5LIST, 61 H5COMPOUND, 62 H5ARRAY, 63 H5VLEN 64 }; 65 66 static std::map<std::string, H5Object::FilterType> filtersName; 67 68 static int getH5ObjectId(int * mlist, void * pvApiCtx); 69 70 static H5Object * getH5Object(int * mlist, void * pvApiCtx); 71 72 static bool isH5Object(int * mlist, void * pvApiCtx); 73 74 static void scilabPrint(const std::string & str); 75 76 static void split(const std::string & str, std::vector<std::string> & v, const char c = '\n'); 77 78 static void readData(const std::string & filename, const std::string & name, const unsigned int size, const double * start, const double * stride, const double * count, const double * block, int pos, void * pvApiCtx); 79 80 static void readData(H5Object & obj, const std::string & name, const unsigned int size, const double * start, const double * stride, const double * count, const double * block, int pos, void * pvApiCtx); 81 82 static void readAttributeData(H5Object & obj, const std::string & path, const std::string & attrName, int pos, void * pvApiCtx); 83 84 static void readAttributeData(const std::string & filename, const std::string & path, const std::string & attrName, int pos, void * pvApiCtx); 85 86 static void deleteObject(const std::string & file, const std::string & name); 87 88 static void deleteObject(const std::string & file, const int size, const char ** names); 89 90 static void deleteObject(const H5Object & parent, const std::string & name); 91 92 static void deleteObject(const H5Object & parent, const int size, const char ** names); 93 94 static void getObject(H5Object & parent, const std::string & location, const bool isAttr, int position, void * pvApiCtx); 95 96 static void createLink(H5Object & parent, const std::string & name, const std::string & targetPath, const bool hard); 97 98 static void createLink(H5Object & parent, const std::string & name, H5Object & targetObject, const bool hard); 99 100 static void createLink(H5Object & parent, const std::string & name, const std::string & targetFile, const std::string & targetPath); 101 102 static void createLink(H5Object & parent, const std::string & name, H5Object & targetObject); 103 104 static void createLink(const std::string & file, const std::string & location, const std::string & name, const std::string & destName, const bool hard); 105 106 static void createLink(const std::string & file, const std::string & location, const std::string & name, const std::string & destFile, const std::string & destName); 107 108 static void copy(H5Object & src, const std::string & slocation, H5Object & dest, const std::string & dlocation); 109 110 static void copy(H5Object & src, const std::string & slocation, const std::string & dfile, const std::string & dlocation); 111 112 static void copy(const std::string & sfile, const std::string & slocation, H5Object & dest, const std::string & dlocation); 113 114 static void copy(const std::string & sfile, const std::string & slocation, const std::string & dfile, const std::string & dlocation); 115 116 static void ls(H5Object & obj, const std::string & name, int position, void * pvApiCtx); 117 118 static void ls(const std::string & path, const std::string & name, int position, void * pvApiCtx); 119 120 static void ls(H5Object & obj, const std::string & name, const std::string & type, int position, void * pvApiCtx); 121 122 static void ls(const std::string & path, const std::string & name, const std::string & type, int position, void * pvApiCtx); 123 124 static bool checkType(const H5Object & obj, const H5ObjectType type); 125 126 static void mount(H5Object & obj, const std::string & location, H5Object & file); 127 128 static void umount(H5Object & obj, const std::string & location); 129 130 static void createGroup(H5Object & parent, const std::string & name); 131 132 static void createGroup(const std::string & file, const std::string & name); 133 134 static void createGroup(H5Object & parent, const int size, const char ** names); 135 136 static void createGroup(const std::string & file, const int size, const char ** names); 137 138 static void label(H5Object & obj, const std::string & location, const unsigned int size, const unsigned int * dim, const char ** names); 139 140 static void label(const std::string & filename, const std::string & location, const unsigned int size, const unsigned int * dim, const char ** names); 141 142 static int * exists(H5Object & obj, const unsigned int size, const char ** locations, const char ** attrNames); 143 144 static int * exists(const std::string & filename, const unsigned int size, const char ** locations, const char ** attrNames); 145 146 template <typename T> create(H5Object & parent,const std::string & name,const unsigned int srank,const hsize_t * sdims,const hsize_t * sstart,const hsize_t * sstride,const hsize_t * scount,const hsize_t * sblock,const hid_t sourceType,void * data,const unsigned int drank,const hsize_t * ddims,const hsize_t * dmaxdims,const hsize_t * dstart,const hsize_t * dstride,const hsize_t * dcount,const hsize_t * dblock,const hid_t targetType)147 static T & create(H5Object & parent, const std::string & name, const unsigned int srank, const hsize_t * sdims, const hsize_t * sstart, const hsize_t * sstride, const hsize_t * scount, const hsize_t * sblock, const hid_t sourceType, void * data, const unsigned int drank, const hsize_t * ddims, const hsize_t * dmaxdims, const hsize_t * dstart, const hsize_t * dstride, const hsize_t * dcount, const hsize_t * dblock, const hid_t targetType) 148 { 149 hid_t obj; 150 hid_t srcspace; 151 hid_t targetspace; 152 hid_t targettype; 153 hsize_t * newdims = 0; 154 bool mustDelete = false; 155 H5T_cdata_t * pcdata = 0; 156 bool chunked = false; 157 158 if (srank > __SCILAB_HDF5_MAX_DIMS__ || drank > __SCILAB_HDF5_MAX_DIMS__) 159 { 160 throw H5Exception(__LINE__, __FILE__, _("Invalid rank, must be in the interval [0, %d]."), __SCILAB_HDF5_MAX_DIMS__); 161 } 162 163 if (targetType == (hid_t) - 1) 164 { 165 targettype = H5Tcopy(sourceType); 166 } 167 else 168 { 169 targettype = H5Tcopy(targetType); 170 } 171 172 if (!H5Tfind(sourceType, targettype, &pcdata)) 173 { 174 H5Tclose(targettype); 175 throw H5Exception(__LINE__, __FILE__, _("No converter found for the specified target datatype.")); 176 } 177 178 srcspace = H5Screate_simple(srank, sdims, 0); 179 if (srcspace < 0) 180 { 181 H5Tclose(targettype); 182 throw H5Exception(__LINE__, __FILE__, _("Cannot create a new dataspace.")); 183 } 184 185 try 186 { 187 newdims = H5Dataspace::select(srcspace, srank, sstart, sstride, scount, sblock); 188 } 189 catch (const H5Exception & /*e*/) 190 { 191 H5Tclose(targettype); 192 H5Sclose(srcspace); 193 throw; 194 } 195 196 if (ddims) 197 { 198 targetspace = H5Screate_simple(drank, ddims, dmaxdims); 199 if (targetspace < 0) 200 { 201 if (newdims) 202 { 203 delete[] newdims; 204 } 205 H5Sclose(srcspace); 206 H5Tclose(targettype); 207 throw H5Exception(__LINE__, __FILE__, _("Invalid target dataspace.")); 208 } 209 if (dmaxdims) 210 { 211 for (unsigned int i = 0; i < drank; i++) 212 { 213 if (ddims[i] != dmaxdims[i]) 214 { 215 chunked = true; 216 break; 217 } 218 } 219 } 220 } 221 else if (newdims) 222 { 223 targetspace = H5Screate_simple(srank, newdims, 0); 224 if (targetspace < 0) 225 { 226 delete[] newdims; 227 H5Sclose(srcspace); 228 H5Tclose(targettype); 229 throw H5Exception(__LINE__, __FILE__, _("Cannot create a new dataspace.")); 230 } 231 } 232 else 233 { 234 targetspace = (hid_t) - 1; 235 } 236 237 if (newdims) 238 { 239 delete[] newdims; 240 } 241 242 if (targetspace != -1 && dstart) 243 { 244 try 245 { 246 hsize_t * _newdims = H5Dataspace::select(targetspace, drank, dstart, dstride, dcount, dblock); 247 if (_newdims) 248 { 249 delete[] _newdims; 250 } 251 } 252 catch (const H5Exception & /*e*/) 253 { 254 H5Tclose(targettype); 255 H5Sclose(targetspace); 256 H5Sclose(srcspace); 257 throw; 258 } 259 } 260 261 try 262 { 263 obj = T::create(parent, name, sourceType, targettype, srcspace, targetspace, data, chunked); 264 H5Sclose(srcspace); 265 if (targetspace >= 0) 266 { 267 H5Sclose(targetspace); 268 } 269 } 270 catch (const H5Exception & /*e*/) 271 { 272 H5Tclose(targettype); 273 H5Sclose(srcspace); 274 if (targetspace >= 0) 275 { 276 H5Sclose(targetspace); 277 } 278 throw; 279 } 280 281 H5Tclose(targettype); 282 283 return *new T(parent, obj, name); 284 } 285 286 static void getScilabData(hid_t * type, unsigned int * ndims, hsize_t ** dims, void ** data, bool * mustDelete, bool * mustDeleteContent, const bool flip, int rhsPosition, void * pvApiCtx); 287 288 static void getScilabData(hid_t * type, unsigned int * ndims, hsize_t ** dims, void ** data, bool * mustDelete, bool * mustDeleteContent, const bool flip, int * addr, int rhsPosition, void * pvApiCtx); 289 290 template <typename T> createObjectFromStack(const std::string & file,const std::string & location,const std::string & name,const bool flip,void * pvApiCtx,const int rhsPosition,const unsigned int srank,const hsize_t * sdims,const hsize_t * sstart,const hsize_t * sstride,const hsize_t * scount,const hsize_t * sblock,const std::string & targetType,const unsigned int drank,const hsize_t * ddims,const hsize_t * dmaxdims,const hsize_t * dstart,const hsize_t * dstride,const hsize_t * dcount,const hsize_t * dblock)291 static void createObjectFromStack(const std::string & file, const std::string & location, const std::string & name, const bool flip, void * pvApiCtx, const int rhsPosition, const unsigned int srank, const hsize_t * sdims, const hsize_t * sstart, const hsize_t * sstride, const hsize_t * scount, const hsize_t * sblock, const std::string & targetType, const unsigned int drank, const hsize_t * ddims, const hsize_t * dmaxdims, const hsize_t * dstart, const hsize_t * dstride, const hsize_t * dcount, const hsize_t * dblock) 292 { 293 H5File & src = *new H5File(file, "/", "r+"); 294 295 try 296 { 297 createObjectFromStack<T>(src, location, name, flip, pvApiCtx, rhsPosition, srank, sdims, sstart, sstride, scount, sblock, targetType, drank, ddims, dmaxdims, dstart, dstride, dcount, dblock); 298 delete &src; 299 } 300 catch (const H5Exception & /*e*/) 301 { 302 delete &src; 303 throw; 304 } 305 } 306 307 template <typename T> createObjectFromStack(H5Object & obj,const std::string & location,const std::string & name,const bool flip,void * pvApiCtx,const int rhsPosition,const unsigned int srank,const hsize_t * sdims,const hsize_t * sstart,const hsize_t * sstride,const hsize_t * scount,const hsize_t * sblock,const std::string & targetType,const unsigned int drank,const hsize_t * ddims,const hsize_t * dmaxdims,const hsize_t * dstart,const hsize_t * dstride,const hsize_t * dcount,const hsize_t * dblock)308 static void createObjectFromStack(H5Object & obj, const std::string & location, const std::string & name, const bool flip, void * pvApiCtx, const int rhsPosition, const unsigned int srank, const hsize_t * sdims, const hsize_t * sstart, const hsize_t * sstride, const hsize_t * scount, const hsize_t * sblock, const std::string & targetType, const unsigned int drank, const hsize_t * ddims, const hsize_t * dmaxdims, const hsize_t * dstart, const hsize_t * dstride, const hsize_t * dcount, const hsize_t * dblock) 309 { 310 hid_t sourceType = -1;; 311 hid_t targettype; 312 unsigned int rank; 313 hsize_t * dims = 0; 314 void * data = 0; 315 bool mustDelete = false; 316 bool mustDeleteContent = false; 317 H5Object * hobj = 0; 318 T * newobj = 0; 319 bool isReference = false; 320 hsize_t total = 1; 321 322 if (targetType.empty()) 323 { 324 targettype = (hid_t) - 1; 325 } 326 else 327 { 328 targettype = H5Type::getBaseType(targetType); 329 if (targettype < 0) 330 { 331 throw H5Exception(__LINE__, __FILE__, _("Cannot create the target type.")); 332 } 333 334 if (H5Tequal(targettype, H5T_STD_REF_OBJ)) 335 { 336 isReference = true; 337 } 338 } 339 340 try 341 { 342 hobj = H5Object::isEmptyPath(location) ? &obj : &H5Object::getObject(obj, location); 343 getScilabData(&sourceType, &rank, &dims, &data, &mustDelete, &mustDeleteContent, flip, rhsPosition, pvApiCtx); 344 345 if (sdims) 346 { 347 hsize_t p1 = 1; 348 hsize_t p2 = 1; 349 for (unsigned int i = 0; i < srank; i++) 350 { 351 p1 *= sdims[i]; 352 } 353 for (unsigned int i = 0; i < rank; i++) 354 { 355 p2 *= dims[i]; 356 } 357 358 total = p1; 359 360 if (p1 != p2) 361 { 362 throw H5Exception(__LINE__, __FILE__, _("Incompatible dimensions")); 363 } 364 rank = srank; 365 } 366 else 367 { 368 sdims = dims; 369 for (unsigned int i = 0; i < rank; i++) 370 { 371 total *= sdims[i]; 372 } 373 } 374 375 if (isReference) 376 { 377 herr_t err; 378 hid_t loc; 379 hobj_ref_t * newData = 0; 380 381 if (H5Tget_class(sourceType) != H5T_STRING) 382 { 383 throw H5Exception(__LINE__, __FILE__, _("References must be given as strings")); 384 } 385 386 loc = hobj->getFile().getH5Id(); 387 newData = (hobj_ref_t *)MALLOC(sizeof(hobj_ref_t) * total); 388 389 for (unsigned int i = 0; i < total; i++) 390 { 391 char * _name = static_cast<char **>(data)[i]; 392 err = H5Rcreate(newData + i, loc, _name, H5R_OBJECT, -1); 393 if (err < 0) 394 { 395 FREE(newData); 396 throw H5Exception(__LINE__, __FILE__, _("Invalid path: %s."), _name); 397 } 398 } 399 400 if (mustDeleteContent) 401 { 402 for (unsigned int i = 0; i < total; i++) 403 { 404 FREE(static_cast<void **>(data)[i]); 405 } 406 } 407 if (mustDelete) 408 { 409 FREE(data); 410 } 411 412 data = newData; 413 mustDeleteContent = false; 414 mustDelete = false; 415 416 if (sourceType > 0) 417 { 418 H5Tclose(sourceType); 419 } 420 sourceType = H5Tcopy(targettype); 421 } 422 423 newobj = &create<T>(*hobj, name, rank, sdims, sstart, sstride, scount, sblock, sourceType, data, drank, ddims, dmaxdims, dstart, dstride, dcount, dblock, targettype); 424 } 425 catch (const H5Exception & /*e*/) 426 { 427 if (mustDeleteContent) 428 { 429 for (unsigned int i = 0; i < total; i++) 430 { 431 FREE(static_cast<void **>(data)[i]); 432 } 433 } 434 if (mustDelete) 435 { 436 FREE(data); 437 } 438 if (dims) 439 { 440 delete[] dims; 441 } 442 if (!H5Object::isEmptyPath(location)) 443 { 444 delete hobj; 445 } 446 if (targettype > 0) 447 { 448 H5Tclose(targettype); 449 } 450 451 if (sourceType > 0) 452 { 453 H5Tclose(sourceType); 454 } 455 456 throw; 457 } 458 459 if (newobj) 460 { 461 delete newobj; 462 } 463 464 if (mustDeleteContent) 465 { 466 for (unsigned int i = 0; i < total; i++) 467 { 468 FREE(static_cast<void **>(data)[i]); 469 } 470 } 471 if (mustDelete) 472 { 473 FREE(data); 474 } 475 if (dims) 476 { 477 delete[] dims; 478 } 479 if (!H5Object::isEmptyPath(location)) 480 { 481 delete hobj; 482 } 483 if (targettype > 0) 484 { 485 H5Tclose(targettype); 486 } 487 if (sourceType > 0) 488 { 489 H5Tclose(sourceType); 490 } 491 } 492 493 template <typename T> flip(const unsigned int size,T * data)494 static void flip(const unsigned int size, T * data) 495 { 496 if (!data) 497 { 498 return; 499 } 500 501 for (unsigned int i = 0; i < size / 2; i++) 502 { 503 T x = data[i]; 504 data[i] = data[size - 1 - i]; 505 data[size - 1 - i] = x; 506 } 507 } 508 509 template <typename T> flipAndConvert(const unsigned int size,T * data)510 static hsize_t * flipAndConvert(const unsigned int size, T * data) 511 { 512 if (!data) 513 { 514 return 0; 515 } 516 517 hsize_t * arr = new hsize_t[size]; 518 for (unsigned int i = 0; i < size; i++) 519 { 520 arr[i] = (hsize_t)data[size - 1 - i]; 521 } 522 523 return arr; 524 } 525 526 private: 527 static std::map<std::string, H5Object::FilterType> initFilterNames(); 528 }; 529 } 530 531 #endif // __HDF5SCILAB_HXX__ 532