GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
oct-stream.h
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 (octave_oct_stream_h)
27#define octave_oct_stream_h 1
28
29#include "octave-config.h"
30
31#include <ios>
32#include <iosfwd>
33#include <list>
34#include <map>
35#include <memory>
36#include <string>
37
38// These only appear as reference arguments or return values.
39
40class Cell;
41class octave_value;
43class string_vector;
44
45#include "Array-fwd.h"
46#include "data-conv.h"
47#include "mach-info.h"
48
49namespace octave
50{
51 class interpreter;
52
53 // These are only needed as arguments to private functions, so they
54 // are also treated as private.
55
56 class scanf_format_elt;
57 class scanf_format_list;
58
59 class printf_format_elt;
60 class printf_format_list;
61
62 // Provide an interface for Octave streams.
63
64 class
65 OCTINTERP_API
67 {
68 friend class stream;
69
70 public:
71
72 base_stream (std::ios::openmode arg_md = std::ios::in | std::ios::out,
74 const std::string& encoding = "utf-8")
75 : m_mode (arg_md), m_flt_fmt (ff), m_encoding (encoding),
76 m_fail (false), m_open_state (true), m_errmsg ()
77 { }
78
79 // No copying!
80
81 base_stream (const base_stream&) = delete;
82
83 base_stream& operator = (const base_stream&) = delete;
84
85 virtual ~base_stream (void) = default;
86
87 // The remaining functions are not specific to input or output only,
88 // and must be provided by the derived classes.
89
90 // Position a stream at OFFSET relative to ORIGIN.
91
92 virtual int seek (off_t offset, int origin) = 0;
93
94 // Return current stream position.
95
96 virtual off_t tell (void) = 0;
97
98 // Return TRUE if EOF has been reached on this stream.
99
100 virtual bool eof (void) const = 0;
101
102 // The name of the file.
103
104 virtual std::string name (void) const = 0;
105
106 // If the derived class provides this function and it returns a
107 // pointer to a valid istream, scanf(), read(), getl(), and gets()
108 // will automatically work for this stream.
109
110 virtual std::istream * input_stream (void) { return nullptr; }
111
112 // If the derived class provides this function and it returns a
113 // pointer to a valid ostream, flush(), write(), and printf() will
114 // automatically work for this stream.
115
116 virtual std::ostream * output_stream (void) { return nullptr; }
117
118 // Return TRUE if this stream is open.
119
120 bool is_open (void) const { return m_open_state; }
121
122 virtual void do_close (void) { }
123
124 void close (void)
125 {
126 if (is_open ())
127 {
128 m_open_state = false;
129 do_close ();
130 }
131 }
132
133 virtual int file_number (void) const
134 {
135 // Kluge alert!
136
137 if (name () == "stdin")
138 return 0;
139 else if (name () == "stdout")
140 return 1;
141 else if (name () == "stderr")
142 return 2;
143 else
144 return -1;
145 }
146
147 bool ok (void) const { return ! m_fail; }
148
149 // Return current error message for this stream.
150
151 std::string error (bool clear, int& err_num);
152
153 protected:
154
155 int mode (void) const { return m_mode; }
156
157 mach_info::float_format float_format (void) const { return m_flt_fmt; }
158
159 std::string encoding (void) const { return m_encoding; }
160
161 // Set current error state and set fail to TRUE.
162
163 OCTINTERP_API void error (const std::string& msg);
164 OCTINTERP_API void error (const std::string& who, const std::string& msg);
165
166 // Clear any error message and set fail to FALSE.
167
168 OCTINTERP_API void clear (void);
169
170 // Clear stream state.
171
172 OCTINTERP_API void clearerr (void);
173
174 private:
175
176 // The permission bits for the file. Should be some combination of
177 // std::ios::open_mode bits.
179
180 // Data format.
182
183 // Code page
184 std::string m_encoding;
185
186 // TRUE if an error has occurred.
187 bool m_fail;
188
189 // TRUE if this stream is open.
191
192 // Should contain error message if fail is TRUE.
193 std::string m_errmsg;
194
195 // Functions that are defined for all input streams (input streams
196 // are those that define is).
197
198 OCTINTERP_API std::string
199 do_gets (octave_idx_type max_len, bool& err, bool strip_newline,
200 const std::string& who /* = "gets" */);
201
202 OCTINTERP_API std::string
203 getl (octave_idx_type max_len, bool& err,
204 const std::string& who /* = "getl" */);
205 OCTINTERP_API std::string
206 gets (octave_idx_type max_len, bool& err,
207 const std::string& who /* = "gets" */);
208 OCTINTERP_API off_t
209 skipl (off_t count, bool& err, const std::string& who /* = "skipl" */);
210
211 OCTINTERP_API octave_value
212 do_scanf (scanf_format_list& fmt_list, octave_idx_type nr,
213 octave_idx_type nc, bool one_elt_size_spec,
214 octave_idx_type& count, const std::string& who /* = "scanf" */);
215
216 OCTINTERP_API octave_value
217 scanf (const std::string& fmt, const Array<double>& size,
218 octave_idx_type& count, const std::string& who /* = "scanf" */);
219
220 OCTINTERP_API bool
221 do_oscanf (const scanf_format_elt *elt, octave_value&,
222 const std::string& who /* = "scanf" */);
223
224 OCTINTERP_API octave_value_list
225 oscanf (const std::string& fmt, const std::string& who /* = "scanf" */);
226
227 OCTINTERP_API octave_value
228 do_textscan (const std::string& fmt, octave_idx_type ntimes,
229 const octave_value_list& options,
230 const std::string& who, octave_idx_type& count);
231
232 // Functions that are defined for all output streams (output streams
233 // are those that define os).
234
235 OCTINTERP_API int flush (void);
236
237 OCTINTERP_API int
238 do_numeric_printf_conv (std::ostream& os, const printf_format_elt *elt,
239 int nsa, int sa_1, int sa_2,
240 const octave_value& val,
241 const std::string& who);
242
243 OCTINTERP_API void field_width_error (const std::string& who) const;
244
245 OCTINTERP_API int
246 do_printf (printf_format_list& fmt_list, const octave_value_list& args,
247 const std::string& who /* = "printf" */);
248
249 OCTINTERP_API int
250 printf (const std::string& fmt, const octave_value_list& args,
251 const std::string& who /* = "printf" */);
252
253 OCTINTERP_API int
254 puts (const std::string& s, const std::string& who /* = "puts" */);
255
256 // We can always do this in terms of seek(), so the derived class
257 // only has to provide that.
258
259 OCTINTERP_API void
260 invalid_operation (const std::string& who, const char *rw);
261 };
262
263 class
264 OCTINTERP_API
265 stream
266 {
267 public:
268
269 // BS must be allocated with new or nullptr.
270 stream (base_stream *bs = nullptr) : m_rep (bs) { }
271
272 stream (const stream&) = default;
273
274 stream& operator = (const stream&) = default;
275
276 ~stream (void) = default;
277
278 OCTINTERP_API int flush (void);
279
280 OCTINTERP_API std::string
281 getl (octave_idx_type max_len, bool& err,
282 const std::string& who /* = "getl" */);
283
284 OCTINTERP_API std::string
285 getl (const octave_value& max_len, bool& err,
286 const std::string& who /* = "getl" */);
287
288 OCTINTERP_API std::string
289 gets (octave_idx_type max_len, bool& err,
290 const std::string& who /* = "gets" */);
291
292 OCTINTERP_API std::string
293 gets (const octave_value& max_len, bool& err,
294 const std::string& who /* = "gets" */);
295
296 OCTINTERP_API off_t
297 skipl (off_t count, bool& err, const std::string& who /* = "skipl" */);
298
299 OCTINTERP_API off_t
300 skipl (const octave_value& count, bool& err,
301 const std::string& who /* = "skipl" */);
302
303 OCTINTERP_API int seek (off_t offset, int origin);
304
305 OCTINTERP_API int
306 seek (const octave_value& offset, const octave_value& origin);
307
308 OCTINTERP_API off_t tell (void);
309
310 OCTINTERP_API int rewind (void);
311
312 OCTINTERP_API bool is_open (void) const;
313
314 OCTINTERP_API void close (void);
315
316 OCTINTERP_API octave_value
317 read (const Array<double>& size, octave_idx_type block_size,
318 oct_data_conv::data_type input_type,
319 oct_data_conv::data_type output_type,
321 octave_idx_type& count);
322
323 OCTINTERP_API octave_idx_type
324 write (const octave_value& data, octave_idx_type block_size,
325 oct_data_conv::data_type output_type,
327
328 OCTINTERP_API bool write_bytes (const void *data, std::size_t n_elts);
329
330 OCTINTERP_API bool skip_bytes (std::size_t n_elts);
331
332 template <typename T>
333 OCTINTERP_API octave_idx_type
334 write (const Array<T>& data, octave_idx_type block_size,
335 oct_data_conv::data_type output_type,
337
338 OCTINTERP_API octave_value
339 scanf (const std::string& fmt, const Array<double>& size,
340 octave_idx_type& count, const std::string& who /* = "scanf" */);
341
342 OCTINTERP_API octave_value
343 scanf (const octave_value& fmt, const Array<double>& size,
344 octave_idx_type& count, const std::string& who /* = "scanf" */);
345
346 OCTINTERP_API octave_value_list
347 oscanf (const std::string& fmt, const std::string& who /* = "scanf" */);
348
349 OCTINTERP_API octave_value_list
350 oscanf (const octave_value& fmt, const std::string& who /* = "scanf" */);
351
352 OCTINTERP_API octave_value
353 textscan (const std::string& fmt, octave_idx_type ntimes,
354 const octave_value_list& options,
355 const std::string& who, octave_idx_type& count);
356
357 OCTINTERP_API int
358 printf (const std::string& fmt, const octave_value_list& args,
359 const std::string& who /* = "printf" */);
360
361 OCTINTERP_API int
362 printf (const octave_value& fmt, const octave_value_list& args,
363 const std::string& who /* = "printf" */);
364
365 OCTINTERP_API int
366 puts (const std::string& s, const std::string& who /* = "puts" */);
367 OCTINTERP_API int
368 puts (const octave_value& s, const std::string& who /* = "puts" */);
369
370 OCTINTERP_API bool eof (void) const;
371
372 OCTINTERP_API std::string error (bool clear, int& err_num);
373
374 std::string error (bool clear = false)
375 {
376 int err_num;
377 return error (clear, err_num);
378 }
379
380 // Set the error message and state.
381
382 void error (const std::string& msg)
383 {
384 if (m_rep)
385 m_rep->error (msg);
386 }
387
388 void error (const char *msg) { error (std::string (msg)); }
389
390 int file_number (void) { return m_rep ? m_rep->file_number () : -1; }
391
392 bool is_valid (void) const { return bool (m_rep); }
393
394 bool ok (void) const { return m_rep && m_rep->ok (); }
395
396 operator bool () const { return ok (); }
397
398 OCTINTERP_API std::string name (void) const;
399
400 OCTINTERP_API int mode (void) const;
401
402 OCTINTERP_API mach_info::float_format float_format (void) const;
403
404 OCTINTERP_API static std::string mode_as_string (int mode);
405
406 std::string encoding (void)
407 {
408 return m_rep ? m_rep->encoding () : std::string ();
409 }
410
411 std::istream * input_stream (void)
412 {
413 return m_rep ? m_rep->input_stream () : nullptr;
414 }
415
416 std::ostream * output_stream (void)
417 {
418 return m_rep ? m_rep->output_stream () : nullptr;
419 }
420
421 void clearerr (void) { if (m_rep) m_rep->clearerr (); }
422
423 private:
424
425 // The actual representation of this stream.
426 std::shared_ptr<base_stream> m_rep;
427
428 bool stream_ok (bool clear = true) const
429 {
430 bool retval = true;
431
432 if (m_rep)
433 {
434 if (clear)
435 m_rep->clear ();
436 }
437 else
438 retval = false;
439
440 return retval;
441 }
442
443 void invalid_operation (const std::string& who, const char *rw)
444 {
445 if (m_rep)
446 m_rep->invalid_operation (who, rw);
447 }
448
449 OCTINTERP_API octave_value
450 finalize_read (std::list<void *>& input_buf_list,
451 octave_idx_type input_buf_elts,
452 octave_idx_type elts_read,
454 oct_data_conv::data_type input_type,
455 oct_data_conv::data_type output_type,
457 };
458
459 class
460 OCTINTERP_API
462 {
463 public:
464
465 OCTINTERP_API stream_list (interpreter& interp);
466
467 stream_list (const stream_list&) = delete;
468 stream_list& operator = (const stream_list&) = delete;
469
470 OCTINTERP_API ~stream_list (void);
471
472 OCTINTERP_API int insert (stream& os);
473
474 OCTINTERP_API stream lookup (int fid, const std::string& who = "") const;
475 OCTINTERP_API stream
476 lookup (const octave_value& fid, const std::string& who = "") const;
477
478 OCTINTERP_API int remove (int fid, const std::string& who = "");
479 OCTINTERP_API int remove (const octave_value& fid, const std::string& who = "");
480
481 OCTINTERP_API void clear (bool flush = true);
482
483 OCTINTERP_API string_vector get_info (int fid) const;
484 OCTINTERP_API string_vector get_info (const octave_value& fid) const;
485
486 OCTINTERP_API std::string list_open_files (void) const;
487
488 OCTINTERP_API octave_value open_file_numbers (void) const;
489
490 OCTINTERP_API int get_file_number (const octave_value& fid) const;
491
492 OCTINTERP_API octave_value stdin_file (void) const;
493 OCTINTERP_API octave_value stdout_file (void) const;
494 OCTINTERP_API octave_value stderr_file (void) const;
495
496 private:
497
498 typedef std::map<int, stream> ostrl_map;
499
501
502 mutable ostrl_map::const_iterator m_lookup_cache;
503
507 };
508}
509
510#endif
octave_idx_type lookup(const T *x, octave_idx_type n, T y)
Definition: Cell.h:43
virtual bool eof(void) const =0
std::string m_encoding
Definition: oct-stream.h:184
bool is_open(void) const
Definition: oct-stream.h:120
virtual void do_close(void)
Definition: oct-stream.h:122
void close(void)
Definition: oct-stream.h:124
std::string m_errmsg
Definition: oct-stream.h:193
bool ok(void) const
Definition: oct-stream.h:147
virtual int seek(off_t offset, int origin)=0
mach_info::float_format float_format(void) const
Definition: oct-stream.h:157
mach_info::float_format m_flt_fmt
Definition: oct-stream.h:181
base_stream(const base_stream &)=delete
base_stream(std::ios::openmode arg_md=std::ios::in|std::ios::out, mach_info::float_format ff=mach_info::native_float_format(), const std::string &encoding="utf-8")
Definition: oct-stream.h:72
int mode(void) const
Definition: oct-stream.h:155
virtual std::istream * input_stream(void)
Definition: oct-stream.h:110
virtual std::ostream * output_stream(void)
Definition: oct-stream.h:116
virtual std::string name(void) const =0
std::string encoding(void) const
Definition: oct-stream.h:159
virtual ~base_stream(void)=default
virtual off_t tell(void)=0
virtual int file_number(void) const
Definition: oct-stream.h:133
ostrl_map::const_iterator m_lookup_cache
Definition: oct-stream.h:502
std::map< int, stream > ostrl_map
Definition: oct-stream.h:498
stream_list(const stream_list &)=delete
void error(const std::string &msg)
Definition: oct-stream.h:382
void invalid_operation(const std::string &who, const char *rw)
Definition: oct-stream.h:443
~stream(void)=default
std::istream * input_stream(void)
Definition: oct-stream.h:411
bool ok(void) const
Definition: oct-stream.h:394
void clearerr(void)
Definition: oct-stream.h:421
std::ostream * output_stream(void)
Definition: oct-stream.h:416
bool stream_ok(bool clear=true) const
Definition: oct-stream.h:428
OCTINTERP_API octave_idx_type write(const Array< T > &data, octave_idx_type block_size, oct_data_conv::data_type output_type, octave_idx_type skip, mach_info::float_format flt_fmt)
std::shared_ptr< base_stream > m_rep
Definition: oct-stream.h:426
stream(base_stream *bs=nullptr)
Definition: oct-stream.h:270
bool is_valid(void) const
Definition: oct-stream.h:392
std::string encoding(void)
Definition: oct-stream.h:406
void error(const char *msg)
Definition: oct-stream.h:388
stream(const stream &)=default
int file_number(void)
Definition: oct-stream.h:390
std::string error(bool clear=false)
Definition: oct-stream.h:374
void error(const char *fmt,...)
Definition: error.cc:980
QString name
float_format native_float_format(void)
Definition: mach-info.cc:65