GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
ov-legacy-range.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1996-2022 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include <istream>
31#include <ostream>
32#include <sstream>
33
34#include "lo-ieee.h"
35#include "lo-utils.h"
36
37#include "variables.h"
38#include "error.h"
39#include "ovl.h"
40#include "oct-hdf5.h"
41#include "ov-legacy-range.h"
42#include "ov-range.h"
43#include "ov-re-mat.h"
44#include "ov-scalar.h"
45#include "pr-output.h"
46
47#include "byte-swap.h"
48#include "ls-ascii-helper.h"
49#include "ls-hdf5.h"
50#include "ls-utils.h"
51
52#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
53# pragma GCC diagnostic push
54# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
55#endif
56
58
60 : octave_base_value (), range () { }
61
63 : octave_base_value (), range (r)
64{
65 if (range.numel () < 0 && range.numel () != -2)
66 error ("invalid range");
67}
68
69static octave_base_value *
71{
72 const octave_legacy_range& v = dynamic_cast<const octave_legacy_range&> (a);
73
74 return new octave_matrix (v.matrix_value ());
75}
76
79{
82}
83
86{
87 octave_base_value *retval = nullptr;
88
89 switch (range.numel ())
90 {
91 case 1:
92 retval = new octave_scalar (range.base ());
93 break;
94
95 case 0:
96 retval = new octave_matrix (Matrix (1, 0));
97 break;
98
99 case -2:
100 retval = new octave_matrix (range.matrix_value ());
101 break;
102
103 default:
104 {
105 if (range.increment () == 0)
106 retval = new octave_matrix (range.matrix_value ());
107 else
108 retval = new octave_range
109 (octave::range<double> (range.base (), range.increment (),
110 range.limit (), range.numel ()));
111 }
112 break;
113 }
114
115 return retval;
116}
117
118// Skip white space and comments on stream IS.
119
120static void
121skip_comments (std::istream& is)
122{
123 char c = '\0';
124 while (is.get (c))
125 {
126 if (c == ' ' || c == '\t' || c == '\n')
127 ; // Skip whitespace on way to beginning of next line.
128 else
129 break;
130 }
131
132 octave::skip_until_newline (is, false);
133}
134
135bool
137{
138 // # base, limit, range comment added by save ().
139 skip_comments (is);
140
141 double base, limit, inc;
142 is >> base >> limit >> inc;
143
144 if (! is)
145 error ("load: failed to load range constant");
146
147 if (inc != 0)
148 range = Range (base, limit, inc);
149 else
150 range = Range (base, inc, static_cast<octave_idx_type> (limit));
151
152 return true;
153}
154
155bool
156octave_legacy_range::load_binary (std::istream& is, bool swap,
158{
159 char tmp;
160 if (! is.read (reinterpret_cast<char *> (&tmp), 1))
161 return false;
162 double bas, lim, inc;
163 if (! is.read (reinterpret_cast<char *> (&bas), 8))
164 return false;
165 if (swap)
166 swap_bytes<8> (&bas);
167 if (! is.read (reinterpret_cast<char *> (&lim), 8))
168 return false;
169 if (swap)
170 swap_bytes<8> (&lim);
171 if (! is.read (reinterpret_cast<char *> (&inc), 8))
172 return false;
173 if (swap)
174 swap_bytes<8> (&inc);
175 if (inc != 0)
176 range = Range (bas, lim, inc);
177 else
178 range = Range (bas, inc, static_cast<octave_idx_type> (lim));
179
180 return true;
181}
182
183#if defined (HAVE_HDF5)
184
185// The following subroutines creates an HDF5 representation of the way
186// we will store Octave range types (triplets of floating-point numbers).
187// NUM_TYPE is the HDF5 numeric type to use for storage (e.g.
188// H5T_NATIVE_DOUBLE to save as 'double'). Note that any necessary
189// conversions are handled automatically by HDF5.
190
191static hid_t
192hdf5_make_range_type (hid_t num_type)
193{
194 hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 3);
195
196 H5Tinsert (type_id, "base", 0 * sizeof (double), num_type);
197 H5Tinsert (type_id, "limit", 1 * sizeof (double), num_type);
198 H5Tinsert (type_id, "increment", 2 * sizeof (double), num_type);
199
200 return type_id;
201}
202
203#endif
204
205bool
207{
208 bool retval = false;
209
210#if defined (HAVE_HDF5)
211
212#if defined (HAVE_HDF5_18)
213 hid_t data_hid = H5Dopen (loc_id, name, octave_H5P_DEFAULT);
214#else
215 hid_t data_hid = H5Dopen (loc_id, name);
216#endif
217 hid_t type_hid = H5Dget_type (data_hid);
218
219 hid_t range_type = hdf5_make_range_type (H5T_NATIVE_DOUBLE);
220
221 if (! hdf5_types_compatible (type_hid, range_type))
222 {
223 H5Tclose (range_type);
224 H5Dclose (data_hid);
225 return false;
226 }
227
228 hid_t space_hid = H5Dget_space (data_hid);
229 hsize_t rank = H5Sget_simple_extent_ndims (space_hid);
230
231 if (rank != 0)
232 {
233 H5Tclose (range_type);
234 H5Sclose (space_hid);
235 H5Dclose (data_hid);
236 return false;
237 }
238
239 double rangevals[3];
240 if (H5Dread (data_hid, range_type, octave_H5S_ALL, octave_H5S_ALL,
241 octave_H5P_DEFAULT, rangevals)
242 >= 0)
243 {
244 retval = true;
245 octave_idx_type nel;
247 "OCTAVE_RANGE_NELEM", &nel))
248 range = Range (rangevals[0], rangevals[2], nel);
249 else
250 {
251 if (rangevals[2] != 0)
252 range = Range (rangevals[0], rangevals[1], rangevals[2]);
253 else
254 range = Range (rangevals[0], rangevals[2],
255 static_cast<octave_idx_type> (rangevals[1]));
256 }
257 }
258
259 H5Tclose (range_type);
260 H5Sclose (space_hid);
261 H5Dclose (data_hid);
262
263#else
264 octave_unused_parameter (loc_id);
265 octave_unused_parameter (name);
266
267 warn_load ("hdf5");
268#endif
269
270 return retval;
271}
272
273#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
274# pragma GCC diagnostic pop
275#endif
void swap_bytes< 8 >(void *ptr)
Definition: byte-swap.h:71
Definition: dMatrix.h:42
Definition: Range.h:400
double increment(void) const
Definition: Range.h:465
double base(void) const
Definition: Range.h:462
OCTAVE_API Matrix matrix_value(void) const
Definition: Range.cc:504
double limit(void) const
Definition: Range.h:463
octave_idx_type numel(void) const
Definition: Range.h:476
OCTINTERP_API void warn_load(const char *type) const
Definition: ov-base.cc:1152
virtual Matrix matrix_value(bool=false) const
Definition: ov-base.cc:543
bool load_ascii(std::istream &is)
bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
bool load_hdf5(octave_hdf5_id loc_id, const char *name)
type_conv_info numeric_conversion_function(void) const
octave_base_value * try_narrowing_conversion(void)
static int static_type_id(void)
Definition: ov-re-mat.h:246
const octave_hdf5_id octave_H5P_DEFAULT
const octave_hdf5_id octave_H5S_ALL
void error(const char *fmt,...)
Definition: error.cc:980
QString name
OCTAVE_NAMESPACE_BEGIN void skip_until_newline(std::istream &is, bool keep_newline)
bool hdf5_get_scalar_attr(octave_hdf5_id loc_id, octave_hdf5_id type_id, const char *attr_name, void *buf)
Definition: ls-hdf5.cc:347
bool hdf5_types_compatible(octave_hdf5_id t1, octave_hdf5_id t2)
Definition: ls-hdf5.cc:269
class OCTAVE_API range
Definition: range-fwd.h:33
int64_t octave_hdf5_id
#define H5T_NATIVE_IDX
Definition: oct-hdf5.h:42
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition: ov-base.h:222
static octave_base_value * default_numeric_conversion_function(const octave_base_value &a)
static void skip_comments(std::istream &is)
static hid_t hdf5_make_range_type(hid_t num_type)
octave_double_range octave_range
Definition: ov-range.h:620