Mercurial > octave-nkf
comparison src/load-save.cc @ 4335:a5818cb949fd
[project @ 2003-02-19 20:37:01 by jwe]
author | jwe |
---|---|
date | Wed, 19 Feb 2003 20:37:16 +0000 |
parents | e41906608e0f |
children | 0c69a845ef1a |
comparison
equal
deleted
inserted
replaced
4334:764229f9a5c8 | 4335:a5818cb949fd |
---|---|
1317 H5Eset_auto (err_func, err_func_data); | 1317 H5Eset_auto (err_func, err_func_data); |
1318 | 1318 |
1319 return retval; | 1319 return retval; |
1320 } | 1320 } |
1321 | 1321 |
1322 // The following two subroutines create HDF5 representations of the way | |
1323 // we will store Octave complex and range types (pairs and triplets of | |
1324 // floating-point numbers, respectively). NUM_TYPE is the HDF5 numeric | |
1325 // type to use for storage (e.g. H5T_NATIVE_DOUBLE to save as 'double'). | |
1326 // Note that any necessary conversions are handled automatically by HDF5. | |
1327 | |
1328 static hid_t | |
1329 hdf5_make_complex_type (hid_t num_type) | |
1330 { | |
1331 hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 2); | |
1332 | |
1333 H5Tinsert (type_id, "real", 0 * sizeof (double), num_type); | |
1334 H5Tinsert (type_id, "imag", 1 * sizeof (double), num_type); | |
1335 | |
1336 return type_id; | |
1337 } | |
1338 | |
1339 static hid_t | |
1340 hdf5_make_range_type (hid_t num_type) | |
1341 { | |
1342 hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 3); | |
1343 | |
1344 H5Tinsert (type_id, "base", 0 * sizeof (double), num_type); | |
1345 H5Tinsert (type_id, "limit", 1 * sizeof (double), num_type); | |
1346 H5Tinsert (type_id, "increment", 2 * sizeof (double), num_type); | |
1347 | |
1348 return type_id; | |
1349 } | |
1350 | |
1322 // Callback data structure for passing data to hdf5_read_next_data, below. | 1351 // Callback data structure for passing data to hdf5_read_next_data, below. |
1323 | 1352 |
1324 struct hdf5_callback_data | 1353 struct |
1325 { | 1354 hdf5_callback_data |
1355 { | |
1356 hdf5_callback_data (void) | |
1357 : name (), global (false), tc (), doc (), | |
1358 complex_type (hdf5_make_complex_type (H5T_NATIVE_DOUBLE)), | |
1359 range_type (hdf5_make_range_type (H5T_NATIVE_DOUBLE)), | |
1360 import (false) { } | |
1361 | |
1326 // the following fields are set by hdf5_read_data on successful return: | 1362 // the following fields are set by hdf5_read_data on successful return: |
1327 | 1363 |
1328 // the name of the variable | 1364 // the name of the variable |
1329 char *name; | 1365 std::string name; |
1330 | 1366 |
1331 // whether it is global | 1367 // whether it is global |
1332 bool global; | 1368 bool global; |
1333 | 1369 |
1334 // the value of the variable, in Octave form | 1370 // the value of the variable, in Octave form |
1335 octave_value tc; | 1371 octave_value tc; |
1336 | 1372 |
1337 // a documentation string (NULL if none) | 1373 // a documentation string (NULL if none) |
1338 char *doc; | 1374 std::string doc; |
1339 | 1375 |
1340 // the following fields are input to hdf5_read_data: | 1376 // the following fields are input to hdf5_read_data: |
1341 | 1377 |
1342 // HDF5 rep's of complex and range type | 1378 // HDF5 rep's of complex and range type |
1343 hid_t complex_type, range_type; | 1379 hid_t complex_type, range_type; |
1362 // (e.g. if NAME was a data type we don't recognize). | 1398 // (e.g. if NAME was a data type we don't recognize). |
1363 | 1399 |
1364 static herr_t | 1400 static herr_t |
1365 hdf5_read_next_data (hid_t group_id, const char *name, void *dv) | 1401 hdf5_read_next_data (hid_t group_id, const char *name, void *dv) |
1366 { | 1402 { |
1367 hdf5_callback_data *d = (hdf5_callback_data *) dv; | 1403 hdf5_callback_data *d = static_cast <hdf5_callback_data *> (dv); |
1404 | |
1368 H5G_stat_t info; | 1405 H5G_stat_t info; |
1369 herr_t retval = 0; | 1406 herr_t retval = 0; |
1370 bool ident_valid = valid_identifier (name); | 1407 bool ident_valid = valid_identifier (name); |
1371 | 1408 |
1372 OCTAVE_LOCAL_BUFFER (char, vname, strlen (name) + 1); | 1409 OCTAVE_LOCAL_BUFFER (char, vname, strlen (name) + 1); |
1488 int slen = H5Tget_size (type_id); | 1525 int slen = H5Tget_size (type_id); |
1489 if (slen < 0) | 1526 if (slen < 0) |
1490 retval = -1; // error | 1527 retval = -1; // error |
1491 else | 1528 else |
1492 { | 1529 { |
1493 char *s = new char [slen]; | 1530 OCTAVE_LOCAL_BUFFER (char, s, slen); |
1494 // create datatype for (null-terminated) string | 1531 // create datatype for (null-terminated) string |
1495 // to read into: | 1532 // to read into: |
1496 hid_t st_id = H5Tcopy (H5T_C_S1); | 1533 hid_t st_id = H5Tcopy (H5T_C_S1); |
1497 H5Tset_size (st_id, slen); | 1534 H5Tset_size (st_id, slen); |
1498 if (H5Dread (data_id, st_id, H5S_ALL, H5S_ALL, | 1535 if (H5Dread (data_id, st_id, H5S_ALL, H5S_ALL, |
1499 H5P_DEFAULT, (void *) s) < 0) | 1536 H5P_DEFAULT, (void *) s) < 0) |
1500 { | 1537 { |
1501 delete [] s; | |
1502 retval = -1; // error | 1538 retval = -1; // error |
1503 } | 1539 } |
1504 else | 1540 else |
1505 d->tc = s; | 1541 d->tc = s; |
1506 | 1542 |
1688 // octave list otherwise. | 1724 // octave list otherwise. |
1689 | 1725 |
1690 bool is_list = hdf5_check_attr (subgroup_id, "OCTAVE_LIST"); | 1726 bool is_list = hdf5_check_attr (subgroup_id, "OCTAVE_LIST"); |
1691 | 1727 |
1692 hdf5_callback_data dsub; | 1728 hdf5_callback_data dsub; |
1693 dsub.name = dsub.doc = 0; | 1729 |
1694 dsub.global = 0; | |
1695 dsub.complex_type = d->complex_type; | 1730 dsub.complex_type = d->complex_type; |
1696 dsub.range_type = d->range_type; | 1731 dsub.range_type = d->range_type; |
1697 dsub.import = d->import; | 1732 dsub.import = d->import; |
1698 | 1733 |
1699 herr_t retval2; | 1734 herr_t retval2; |
1706 if (is_list) | 1741 if (is_list) |
1707 lst.append (dsub.tc); | 1742 lst.append (dsub.tc); |
1708 else | 1743 else |
1709 m [dsub.name] = dsub.tc; | 1744 m [dsub.name] = dsub.tc; |
1710 | 1745 |
1711 if (dsub.name) | |
1712 delete [] dsub.name; | |
1713 | |
1714 if (dsub.doc) | |
1715 delete [] dsub.doc; | |
1716 | |
1717 if (have_h5giterate_bug) | 1746 if (have_h5giterate_bug) |
1718 current_item++; // H5Giterate returned the last index processed | 1747 current_item++; // H5Giterate returned the last index processed |
1719 } | 1748 } |
1720 | 1749 |
1721 if (retval2 < 0) | 1750 if (retval2 < 0) |
1750 // get documentation string, if any: | 1779 // get documentation string, if any: |
1751 int comment_length = H5Gget_comment (group_id, name, 0, 0); | 1780 int comment_length = H5Gget_comment (group_id, name, 0, 0); |
1752 | 1781 |
1753 if (comment_length > 1) | 1782 if (comment_length > 1) |
1754 { | 1783 { |
1755 d->doc = new char[comment_length]; | 1784 OCTAVE_LOCAL_BUFFER (char, tdoc, comment_length); |
1756 H5Gget_comment (group_id, name, comment_length, d->doc); | 1785 H5Gget_comment (group_id, name, comment_length, tdoc); |
1786 d->doc = tdoc; | |
1757 } | 1787 } |
1758 else if (strcmp (name, vname) != 0) | 1788 else if (strcmp (name, vname) != 0) |
1759 { | 1789 { |
1760 // the name was changed by import; store the original name | 1790 // the name was changed by import; store the original name |
1761 // as the documentation string: | 1791 // as the documentation string: |
1762 d->doc = new char [strlen (name) + 1]; | 1792 d->doc = name; |
1763 strcpy (d->doc, name); | 1793 } |
1764 } | |
1765 else | |
1766 d->doc = 0; | |
1767 | 1794 |
1768 // copy name (actually, vname): | 1795 // copy name (actually, vname): |
1769 d->name = new char [strlen (vname) + 1]; | 1796 d->name = vname; |
1770 strcpy (d->name, vname); | |
1771 } | 1797 } |
1772 | 1798 |
1773 return retval; | 1799 return retval; |
1774 } | |
1775 | |
1776 // The following two subroutines create HDF5 representations of the way | |
1777 // we will store Octave complex and range types (pairs and triplets of | |
1778 // floating-point numbers, respectively). NUM_TYPE is the HDF5 numeric | |
1779 // type to use for storage (e.g. H5T_NATIVE_DOUBLE to save as 'double'). | |
1780 // Note that any necessary conversions are handled automatically by HDF5. | |
1781 | |
1782 static hid_t | |
1783 hdf5_make_complex_type (hid_t num_type) | |
1784 { | |
1785 hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 2); | |
1786 | |
1787 H5Tinsert (type_id, "real", 0 * sizeof (double), num_type); | |
1788 H5Tinsert (type_id, "imag", 1 * sizeof (double), num_type); | |
1789 | |
1790 return type_id; | |
1791 } | |
1792 | |
1793 static hid_t | |
1794 hdf5_make_range_type (hid_t num_type) | |
1795 { | |
1796 hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 3); | |
1797 | |
1798 H5Tinsert (type_id, "base", 0 * sizeof (double), num_type); | |
1799 H5Tinsert (type_id, "limit", 1 * sizeof (double), num_type); | |
1800 H5Tinsert (type_id, "increment", 2 * sizeof (double), num_type); | |
1801 | |
1802 return type_id; | |
1803 } | 1800 } |
1804 | 1801 |
1805 // Read the next Octave variable from the stream IS, which must really be | 1802 // Read the next Octave variable from the stream IS, which must really be |
1806 // an hdf5_ifstream. Return the variable value in tc, its doc string | 1803 // an hdf5_ifstream. Return the variable value in tc, its doc string |
1807 // in doc, and whether it is global in global. The return value is | 1804 // in doc, and whether it is global in global. The return value is |
1819 doc.resize (0); | 1816 doc.resize (0); |
1820 | 1817 |
1821 hdf5_ifstream& hs = (hdf5_ifstream&) is; | 1818 hdf5_ifstream& hs = (hdf5_ifstream&) is; |
1822 hdf5_callback_data d; | 1819 hdf5_callback_data d; |
1823 | 1820 |
1824 d.name = 0; | |
1825 d.global = 0; | |
1826 d.doc = 0; | |
1827 d.complex_type = hdf5_make_complex_type (H5T_NATIVE_DOUBLE); | |
1828 d.range_type = hdf5_make_range_type (H5T_NATIVE_DOUBLE); | |
1829 d.import = import; | 1821 d.import = import; |
1830 | 1822 |
1831 // Versions of HDF5 prior to 1.2.2 had a bug in H5Giterate where it | 1823 // Versions of HDF5 prior to 1.2.2 had a bug in H5Giterate where it |
1832 // would return the index of the last item processed instead of the | 1824 // would return the index of the last item processed instead of the |
1833 // next item to be processed, forcing us to increment the index manually. | 1825 // next item to be processed, forcing us to increment the index manually. |
1855 | 1847 |
1856 if (H5Giterate_retval > 0) | 1848 if (H5Giterate_retval > 0) |
1857 { | 1849 { |
1858 global = d.global; | 1850 global = d.global; |
1859 tc = d.tc; | 1851 tc = d.tc; |
1860 if (d.doc) | 1852 doc = d.doc; |
1861 doc = d.doc; | |
1862 } | 1853 } |
1863 else | 1854 else |
1864 { | 1855 { |
1865 // an error occurred (H5Giterate_retval < 0) or there are no | 1856 // an error occurred (H5Giterate_retval < 0) or there are no |
1866 // more datasets print an error message if retval < 0? | 1857 // more datasets print an error message if retval < 0? |
1868 } | 1859 } |
1869 | 1860 |
1870 H5Tclose (d.complex_type); | 1861 H5Tclose (d.complex_type); |
1871 H5Tclose (d.range_type); | 1862 H5Tclose (d.range_type); |
1872 | 1863 |
1873 if (d.name) | 1864 if (! d.name.empty ()) |
1874 retval = d.name; | 1865 retval = d.name; |
1875 | 1866 |
1876 return retval; | 1867 return retval; |
1877 } | 1868 } |
1878 | 1869 |