Mercurial > hg > octave-lyh
diff src/oct-stream.h @ 2117:b240b2fce8ed
[project @ 1996-05-10 07:20:36 by jwe]
Initial revision
author | jwe |
---|---|
date | Fri, 10 May 1996 07:20:36 +0000 |
parents | |
children | ee08cc210438 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/src/oct-stream.h @@ -0,0 +1,531 @@ +/* + +Copyright (C) 1996 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#if !defined (octave_octave_stream_h) +#define octave_octave_stream_h 1 + +#include <string> + +#include <iostream.h> +#include <strstream.h> + +#include "Array.h" + +#include "oct-obj.h" +#include "str-vec.h" + +struct +scanf_format_elt +{ + scanf_format_elt (const char *txt = 0, bool d = false, + char typ = '\0', char mod = '\0') + : text (txt), discard (d), type (typ), modifier (mod) { } + + ~scanf_format_elt (void) { delete text; } + + const char *text; + bool discard; + char type; + char modifier; +}; + +class +scanf_format_list +{ +public: + + scanf_format_list (const string& fmt = string ()); + + ~scanf_format_list (void); + + int num_conversions (void) { return nconv; } + + const scanf_format_elt *first (void) + { + curr_idx = 0; + return current (); + } + + const scanf_format_elt *current (void) const + { return list.length () > 0 ? list.elem (curr_idx) : 0; } + + const scanf_format_elt *next (void) + { + curr_idx++; + if (curr_idx >= list.length ()) + curr_idx = 0; + return current (); + } + + void printme (void) const; + + bool ok (void) const { return (nconv >= 0); } + + operator void* () const { return ok () ? (void *) -1 : (void *) 0; } + + bool all_character_conversions (void); + + bool all_numeric_conversions (void); + +private: + + // Number of conversions specified by this format string, or -1 if + // invalid conversions have been found. + int nconv; + + // Index to current element; + int curr_idx; + + // List of format elements. + Array<scanf_format_elt*> list; + + // Temporary buffer. + ostrstream *buf; + + void add_elt_to_list (bool discard, char type, char modifier, + int& num_elts); + + void process_conversion (const string& s, int& i, int n, bool& discard, + char& type, char& modifier, int& num_elts); + + int finish_conversion (const string& s, int& i, int n, bool discard, + char& type, char modifier, int& num_elts); + // No copying! + + scanf_format_list (const scanf_format_list&); + + scanf_format_list& operator = (const scanf_format_list&); +}; + +struct +printf_format_elt +{ + printf_format_elt (const char *txt = 0, int n = 0, char typ = '\0', + char mod = '\0') + : text (txt), args (n), type (typ), modifier (mod) { } + + ~printf_format_elt (void) { delete text; } + + const char *text; + int args; + char type; + char modifier; +}; + +class +printf_format_list +{ +public: + + printf_format_list (const string& fmt = string ()); + + ~printf_format_list (void); + + int num_conversions (void) { return nconv; } + + const printf_format_elt *first (void) + { + curr_idx = 0; + return current (); + } + + const printf_format_elt *current (void) const + { return list.length () > 0 ? list.elem (curr_idx) : 0; } + + const printf_format_elt *next (void) + { + curr_idx++; + if (curr_idx >= list.length ()) + curr_idx = 0; + return current (); + } + + void printme (void) const; + + bool ok (void) const { return (nconv >= 0); } + + operator void* () const { return ok () ? (void *) -1 : (void *) 0; } + +private: + + // Number of conversions specified by this format string, or -1 if + // invalid conversions have been found. + int nconv; + + // Index to current element; + int curr_idx; + + // List of format elements. + Array<printf_format_elt*> list; + + // Temporary buffer. + ostrstream *buf; + + void add_elt_to_list (int args, char type, char modifier, + int& num_elts); + + void process_conversion (const string& s, int& i, int n, int& args, + char& modifier, char& type, int& num_elts); + + void finish_conversion (const string& s, int& i, int args, + char modifier, char& type, int& num_elts); + + // No copying! + + printf_format_list (const printf_format_list&); + + printf_format_list& operator = (const printf_format_list&); +}; + +// Provide an interface for Octave streams. + +class +octave_base_stream +{ +friend class octave_stream; + +public: + + enum arch_type + { + at_unknown, + at_native + }; + + enum data_type + { + dt_unknown, + dt_char, + dt_schar, + dt_uchar, + dt_short, + dt_ushort, + dt_int, + dt_uint, + dt_long, + dt_ulong, + dt_float, + dt_double, + dt_float_complex, + dt_double_complex + }; + + octave_base_stream (ios::openmode arg_md = ios::in|ios::out, + arch_type arg_at = at_native) + : md (arg_md), at (arg_at), fail (false) { } + + virtual ~octave_base_stream (void) { } + + // The remaining functions are not specific to input or output only, + // and must be provided by the derived classes. + + // Position a stream at OFFSET relative to ORIGIN. + + virtual int seek (streampos offset, ios::seek_dir origin) = 0; + + // Return current stream position. + + virtual long tell (void) const = 0; + + // Return non-zero if EOF has been reached on this stream. + + virtual bool eof (void) const = 0; + + // The name of the file. + + virtual string name (void) = 0; + + // If the derived class provides this function and it returns a + // pointer to a valid istream, scanf(), read(), getl(), and gets() + // will automatically work for this stream. + + virtual istream *input_stream (void) { return 0; } + + // If the derived class provides this function and it returns a + // pointer to a valid ostream, flush(), write(), and printf() will + // automatically work for this stream. + + virtual ostream *output_stream (void) { return 0; } + + bool ok (void) const { return ! fail; } + + // Return current error message for this stream. + + string error (bool clear, int& errno); + +protected: + + int mode (void) { return md; } + + arch_type architecture (void) { return at; } + + // Set current error state and set fail to TRUE. + + void error (const string& msg); + + // Clear any error message and set fail to FALSE. + + void clear (void); + +private: + + // The permission bits for the file. Should be some combination of + // ios::open_mode bits. + int md; + + // Data format. + arch_type at; + + // TRUE if an error has occurred. + bool fail; + + // Should contain error message if fail is TRUE. + string errmsg; + + // Functions that are defined for all input streams (input streams + // are those that define is). + + string do_gets (int max_len, bool& err, bool strip_newline, const char *fcn); + + string getl (int max_len, bool& err); + string gets (int max_len, bool& err); + + octave_value do_read (int nr, int nc, data_type dt, int skip, + arch_type at, int& count); + + octave_value read (const Matrix& size, data_type dt, int skip, + arch_type at, int& count); + + octave_value do_char_scanf (scanf_format_list& fmt_list, + int nr, int nc, int& count); + + octave_value do_real_scanf (scanf_format_list& fmt_list, + int nr, int nc, int& count); + + octave_value do_scanf (scanf_format_list& fmt_list, int nr, int nc, + int& count); + + octave_value scanf (const string& fmt, const Matrix& size, int& count); + + // Functions that are defined for all output streams (output streams + // are those that define os). + + int flush (void); + + int do_write (const double *d, int n, data_type dt, int skip, + arch_type at); + + int write (const octave_value& data, data_type dt, int skip, + arch_type at); + + int do_printf (printf_format_list& fmt_list, const octave_value_list& args); + + int printf (const string& fmt, const octave_value_list& args); + + int puts (const string& s); + + // We can always do this in terms of seek(), so the derived class + // only has to provide that. + + int rewind (void); + + void invalid_operation (const char *op, const char *rw); + + // No copying! + + octave_base_stream (const octave_base_stream&); + + octave_base_stream& operator = (const octave_base_stream&); +}; + +class +octave_stream +{ +public: + + octave_stream (octave_base_stream *bs = 0) : rep (bs) { } + + ~octave_stream (void) { delete rep; } + + int flush (void); + + string getl (int max_len, bool& err); + string getl (const octave_value& max_len, bool& err); + + string gets (int max_len, bool& err); + string gets (const octave_value& max_len, bool& err); + + int seek (streampos offset, ios::seek_dir origin); + int seek (const octave_value& offset, const octave_value& origin); + + long tell (void) const; + + int rewind (void); + + octave_value read (const Matrix& size, + octave_base_stream::data_type dt, + int skip, octave_base_stream::arch_type at, + int& count); + + int write (const octave_value& data, + octave_base_stream::data_type dt, int skip, + octave_base_stream::arch_type at); + + octave_value scanf (const string& fmt, const Matrix& size, int& count); + + int printf (const string& fmt, const octave_value_list& args); + + int puts (const string& s); + int puts (const octave_value& s); + + bool eof (void) const; + + string error (bool clear, int& errno); + + string error (bool clear = false) + { + int errno; + return error (clear, errno); + } + + bool ok (void) const { return rep && rep->ok (); } + + operator void* () const { return ok () ? (void *) -1 : (void *) 0; } + + string name (void); + + int mode (void); + + octave_base_stream::arch_type architecture (void); + + static string mode_as_string (int mode); + + static string arch_as_string (octave_base_stream::arch_type at); + + static octave_base_stream::data_type string_to_data_type (const string& s); + static octave_base_stream::arch_type string_to_arch_type (const string& s); + +private: + + // The actual representation of this stream. + octave_base_stream *rep; + + void invalid_stream_error (const char *op) const; + + bool stream_ok (const char *op, bool clear = true) const + { + bool retval = true; + + if (rep) + { + if (clear) + rep->clear (); + } + else + { + retval = false; + invalid_stream_error (op); + } + + return retval; + } + + void error (const string& msg) + { + if (rep) + rep->error (msg); + } + + // Must create named streams. + + octave_stream (void); + + // No copying! + + octave_stream (const octave_stream&); + + octave_stream& operator = (const octave_stream&); +}; + +class +octave_stream_list +{ +protected: + + octave_stream_list (void) : list (32), curr_len (0) { } + +public: + + ~octave_stream_list (void) { } + + static int insert (octave_base_stream *obs); + + static octave_stream *lookup (int fid); + static octave_stream *lookup (const octave_value& fid); + + static int remove (int fid); + static int remove (const octave_value& fid); + + static void clear (void); + + static string_vector get_info (int fid); + static string_vector get_info (const octave_value& fid); + + static string list_open_files (void); + + static octave_value open_file_numbers (void); + +private: + + Array<octave_stream*> list; + + int curr_len; + + static octave_stream_list *instance; + + int do_insert (octave_base_stream *obs); + + octave_stream *do_lookup (int fid) const; + octave_stream *do_lookup (const octave_value& fid) const; + + int do_remove (int fid); + int do_remove (const octave_value& fid); + + void do_clear (void); + + string_vector do_get_info (int fid) const; + string_vector do_get_info (const octave_value& fid) const; + + string do_list_open_files (void) const; + + octave_value do_open_file_numbers (void) const; + + int get_file_number (const octave_value& fid) const; +}; + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/