00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #if !defined (octave_octave_stream_h)
00024 #define octave_octave_stream_h 1
00025
00026 class Matrix;
00027 class string_vector;
00028 class octave_value;
00029 class octave_value_list;
00030
00031 #include <iosfwd>
00032 #include <sstream>
00033 #include <string>
00034 #include <map>
00035
00036 #include "Array.h"
00037 #include "data-conv.h"
00038 #include "lo-utils.h"
00039 #include "mach-info.h"
00040 #include "oct-refcount.h"
00041
00042 class
00043 OCTINTERP_API
00044 scanf_format_elt
00045 {
00046 public:
00047
00048 enum special_conversion
00049 {
00050 whitespace_conversion = 1,
00051 literal_conversion = 2
00052 };
00053
00054 scanf_format_elt (const char *txt = 0, int w = 0, bool d = false,
00055 char typ = '\0', char mod = '\0',
00056 const std::string& ch_class = std::string ())
00057 : text (strsave (txt)), width (w), discard (d), type (typ),
00058 modifier (mod), char_class (ch_class) { }
00059
00060 scanf_format_elt (const scanf_format_elt& e)
00061 : text (strsave (e.text)), width (e.width), discard (e.discard),
00062 type (e.type), modifier (e.modifier), char_class (e.char_class) { }
00063
00064 scanf_format_elt& operator = (const scanf_format_elt& e)
00065 {
00066 if (this != &e)
00067 {
00068 text = strsave (e.text);
00069 width = e.width;
00070 discard = e.discard;
00071 type = e.type;
00072 modifier = e.modifier;
00073 char_class = e.char_class;
00074 }
00075
00076 return *this;
00077 }
00078
00079 ~scanf_format_elt (void) { delete [] text; }
00080
00081
00082 const char *text;
00083
00084
00085 int width;
00086
00087
00088 bool discard;
00089
00090
00091
00092 char type;
00093
00094
00095 char modifier;
00096
00097
00098 std::string char_class;
00099 };
00100
00101 class
00102 OCTINTERP_API
00103 scanf_format_list
00104 {
00105 public:
00106
00107 scanf_format_list (const std::string& fmt = std::string ());
00108
00109 ~scanf_format_list (void);
00110
00111 octave_idx_type num_conversions (void) { return nconv; }
00112
00113
00114
00115
00116
00117
00118 octave_idx_type length (void) { return list.length (); }
00119
00120 const scanf_format_elt *first (void)
00121 {
00122 curr_idx = 0;
00123 return current ();
00124 }
00125
00126 const scanf_format_elt *current (void) const
00127 { return list.length () > 0 ? list.elem (curr_idx) : 0; }
00128
00129 const scanf_format_elt *next (bool cycle = true)
00130 {
00131 curr_idx++;
00132
00133 if (curr_idx >= list.length ())
00134 {
00135 if (cycle)
00136 curr_idx = 0;
00137 else
00138 return 0;
00139 }
00140 return current ();
00141 }
00142
00143 void printme (void) const;
00144
00145 bool ok (void) const { return (nconv >= 0); }
00146
00147 operator bool () const { return ok (); }
00148
00149 bool all_character_conversions (void);
00150
00151 bool all_numeric_conversions (void);
00152
00153 private:
00154
00155
00156
00157 octave_idx_type nconv;
00158
00159
00160 octave_idx_type curr_idx;
00161
00162
00163
00164 Array<scanf_format_elt*> list;
00165
00166
00167 std::ostringstream *buf;
00168
00169 void add_elt_to_list (int width, bool discard, char type, char modifier,
00170 octave_idx_type& num_elts,
00171 const std::string& char_class = std::string ());
00172
00173 void process_conversion (const std::string& s, size_t& i, size_t n,
00174 int& width, bool& discard, char& type,
00175 char& modifier, octave_idx_type& num_elts);
00176
00177 int finish_conversion (const std::string& s, size_t& i, size_t n,
00178 int& width, bool discard, char& type,
00179 char modifier, octave_idx_type& num_elts);
00180
00181
00182 scanf_format_list (const scanf_format_list&);
00183
00184 scanf_format_list& operator = (const scanf_format_list&);
00185 };
00186
00187 class
00188 printf_format_elt
00189 {
00190 public:
00191
00192 printf_format_elt (const char *txt = 0, int n = 0, int w = 0,
00193 int p = 0, const std::string& f = std::string (),
00194 char typ = '\0', char mod = '\0')
00195 : text (strsave (txt)), args (n), fw (w), prec (p), flags (f),
00196 type (typ), modifier (mod) { }
00197
00198 printf_format_elt (const printf_format_elt& e)
00199 : text (strsave (e.text)), args (e.args), fw (e.fw), prec (e.prec),
00200 flags (e.flags), type (e.type), modifier (e.modifier) { }
00201
00202 printf_format_elt& operator = (const printf_format_elt& e)
00203 {
00204 if (this != &e)
00205 {
00206 text = strsave (e.text);
00207 args = e.args;
00208 fw = e.fw;
00209 prec = e.prec;
00210 flags = e.flags;
00211 type = e.type;
00212 modifier = e.modifier;
00213 }
00214
00215 return *this;
00216 }
00217
00218 ~printf_format_elt (void) { delete [] text; }
00219
00220
00221 const char *text;
00222
00223
00224 int args;
00225
00226
00227 int fw;
00228
00229
00230 int prec;
00231
00232
00233 std::string flags;
00234
00235
00236
00237 char type;
00238
00239
00240 char modifier;
00241 };
00242
00243 class
00244 OCTINTERP_API
00245 printf_format_list
00246 {
00247 public:
00248
00249 printf_format_list (const std::string& fmt = std::string ());
00250
00251 ~printf_format_list (void);
00252
00253 octave_idx_type num_conversions (void) { return nconv; }
00254
00255 const printf_format_elt *first (void)
00256 {
00257 curr_idx = 0;
00258 return current ();
00259 }
00260
00261 const printf_format_elt *current (void) const
00262 { return list.length () > 0 ? list.elem (curr_idx) : 0; }
00263
00264 const printf_format_elt *next (bool cycle = true)
00265 {
00266 curr_idx++;
00267
00268 if (curr_idx >= list.length ())
00269 {
00270 if (cycle)
00271 curr_idx = 0;
00272 else
00273 return 0;
00274 }
00275
00276 return current ();
00277 }
00278
00279 bool last_elt_p (void) { return (curr_idx + 1 == list.length ()); }
00280
00281 void printme (void) const;
00282
00283 bool ok (void) const { return (nconv >= 0); }
00284
00285 operator bool () const { return ok (); }
00286
00287 private:
00288
00289
00290
00291 octave_idx_type nconv;
00292
00293
00294 octave_idx_type curr_idx;
00295
00296
00297
00298 Array<printf_format_elt*> list;
00299
00300
00301 std::ostringstream *buf;
00302
00303 void add_elt_to_list (int args, const std::string& flags, int fw,
00304 int prec, char type, char modifier,
00305 octave_idx_type& num_elts);
00306
00307 void process_conversion (const std::string& s, size_t& i, size_t n,
00308 int& args, std::string& flags, int& fw,
00309 int& prec, char& modifier, char& type,
00310 octave_idx_type& num_elts);
00311
00312 void finish_conversion (const std::string& s, size_t& i, int args,
00313 const std::string& flags, int fw, int prec,
00314 char modifier, char& type,
00315 octave_idx_type& num_elts);
00316
00317
00318
00319 printf_format_list (const printf_format_list&);
00320
00321 printf_format_list& operator = (const printf_format_list&);
00322 };
00323
00324
00325
00326 class
00327 OCTINTERP_API
00328 octave_base_stream
00329 {
00330 friend class octave_stream;
00331
00332 public:
00333
00334 octave_base_stream (std::ios::openmode arg_md = std::ios::in|std::ios::out,
00335 oct_mach_info::float_format ff
00336 = oct_mach_info::native_float_format ())
00337 : count (0), md (arg_md), flt_fmt (ff), fail (false), open_state (true),
00338 errmsg ()
00339 { }
00340
00341 virtual ~octave_base_stream (void) { }
00342
00343
00344
00345
00346
00347
00348 virtual int seek (long offset, int origin) = 0;
00349
00350
00351
00352 virtual long tell (void) = 0;
00353
00354
00355
00356 virtual bool eof (void) const = 0;
00357
00358
00359
00360 virtual std::string name (void) const = 0;
00361
00362
00363
00364
00365
00366 virtual std::istream *input_stream (void) { return 0; }
00367
00368
00369
00370
00371
00372 virtual std::ostream *output_stream (void) { return 0; }
00373
00374
00375
00376 bool is_open (void) const { return open_state; }
00377
00378 virtual void do_close (void) { }
00379
00380 void close (void)
00381 {
00382 if (is_open ())
00383 {
00384 open_state = false;
00385 do_close ();
00386 }
00387 }
00388
00389 virtual int file_number (void) const
00390 {
00391
00392
00393 if (name () == "stdin")
00394 return 0;
00395 else if (name () == "stdout")
00396 return 1;
00397 else if (name () == "stderr")
00398 return 2;
00399 else
00400 return -1;
00401 }
00402
00403 bool ok (void) const { return ! fail; }
00404
00405
00406
00407 std::string error (bool clear, int& err_num);
00408
00409 protected:
00410
00411 int mode (void) const { return md; }
00412
00413 oct_mach_info::float_format float_format (void) const { return flt_fmt; }
00414
00415
00416
00417 void error (const std::string& msg);
00418 void error (const std::string& who, const std::string& msg);
00419
00420
00421
00422 void clear (void);
00423
00424
00425
00426 void clearerr (void);
00427
00428 private:
00429
00430
00431 octave_refcount<octave_idx_type> count;
00432
00433
00434
00435 int md;
00436
00437
00438 oct_mach_info::float_format flt_fmt;
00439
00440
00441 bool fail;
00442
00443
00444 bool open_state;
00445
00446
00447 std::string errmsg;
00448
00449
00450
00451
00452 std::string do_gets (octave_idx_type max_len, bool& err, bool strip_newline,
00453 const std::string& who );
00454
00455 std::string getl (octave_idx_type max_len, bool& err, const std::string& who );
00456 std::string gets (octave_idx_type max_len, bool& err, const std::string& who );
00457 long skipl (long count, bool& err, const std::string& who );
00458
00459 octave_value do_scanf (scanf_format_list& fmt_list, octave_idx_type nr, octave_idx_type nc,
00460 bool one_elt_size_spec, octave_idx_type& count,
00461 const std::string& who );
00462
00463 octave_value scanf (const std::string& fmt, const Array<double>& size,
00464 octave_idx_type& count, const std::string& who );
00465
00466 bool do_oscanf (const scanf_format_elt *elt, octave_value&,
00467 const std::string& who );
00468
00469 octave_value_list oscanf (const std::string& fmt,
00470 const std::string& who );
00471
00472
00473
00474
00475 int flush (void);
00476
00477 int do_printf (printf_format_list& fmt_list, const octave_value_list& args,
00478 const std::string& who );
00479
00480 int printf (const std::string& fmt, const octave_value_list& args,
00481 const std::string& who );
00482
00483 int puts (const std::string& s, const std::string& who );
00484
00485
00486
00487
00488 void invalid_operation (const std::string& who, const char *rw);
00489
00490
00491
00492 octave_base_stream (const octave_base_stream&);
00493
00494 octave_base_stream& operator = (const octave_base_stream&);
00495 };
00496
00497 class
00498 OCTINTERP_API
00499 octave_stream
00500 {
00501 public:
00502
00503 octave_stream (octave_base_stream *bs = 0);
00504
00505 ~octave_stream (void);
00506
00507 octave_stream (const octave_stream&);
00508
00509 octave_stream& operator = (const octave_stream&);
00510
00511 int flush (void);
00512
00513 std::string getl (octave_idx_type max_len, bool& err, const std::string& who );
00514 std::string getl (const octave_value& max_len, bool& err,
00515 const std::string& who );
00516
00517 std::string gets (octave_idx_type max_len, bool& err, const std::string& who );
00518 std::string gets (const octave_value& max_len, bool& err,
00519 const std::string& who );
00520
00521 long skipl (long count, bool& err, const std::string& who );
00522 long skipl (const octave_value& count, bool& err, const std::string& who );
00523
00524 int seek (long offset, int origin);
00525 int seek (const octave_value& offset, const octave_value& origin);
00526
00527 long tell (void);
00528
00529 int rewind (void);
00530
00531 bool is_open (void) const;
00532
00533 void close (void);
00534
00535 octave_value read (const Array<double>& size, octave_idx_type block_size,
00536 oct_data_conv::data_type input_type,
00537 oct_data_conv::data_type output_type,
00538 octave_idx_type skip, oct_mach_info::float_format flt_fmt,
00539 octave_idx_type& count);
00540
00541 octave_idx_type write (const octave_value& data, octave_idx_type block_size,
00542 oct_data_conv::data_type output_type,
00543 octave_idx_type skip, oct_mach_info::float_format flt_fmt);
00544
00545 template <class T>
00546 octave_idx_type write (const Array<T>&, octave_idx_type block_size,
00547 oct_data_conv::data_type output_type,
00548 octave_idx_type skip, oct_mach_info::float_format flt_fmt);
00549
00550 octave_value scanf (const std::string& fmt, const Array<double>& size,
00551 octave_idx_type& count, const std::string& who );
00552
00553 octave_value scanf (const octave_value& fmt, const Array<double>& size,
00554 octave_idx_type& count, const std::string& who );
00555
00556 octave_value_list oscanf (const std::string& fmt,
00557 const std::string& who );
00558
00559 octave_value_list oscanf (const octave_value& fmt,
00560 const std::string& who );
00561
00562 int printf (const std::string& fmt, const octave_value_list& args,
00563 const std::string& who );
00564
00565 int printf (const octave_value& fmt, const octave_value_list& args,
00566 const std::string& who );
00567
00568 int puts (const std::string& s, const std::string& who );
00569 int puts (const octave_value& s, const std::string& who );
00570
00571 bool eof (void) const;
00572
00573 std::string error (bool clear, int& err_num);
00574
00575 std::string error (bool clear = false)
00576 {
00577 int err_num;
00578 return error (clear, err_num);
00579 }
00580
00581
00582
00583 void error (const std::string& msg)
00584 {
00585 if (rep)
00586 rep->error (msg);
00587 }
00588
00589 void error (const char *msg) { error (std::string (msg)); }
00590
00591 int file_number (void) { return rep ? rep->file_number () : -1; }
00592
00593 bool is_valid (void) const { return (rep != 0); }
00594
00595 bool ok (void) const { return rep && rep->ok (); }
00596
00597 operator bool () const { return ok (); }
00598
00599 std::string name (void) const;
00600
00601 int mode (void) const;
00602
00603 oct_mach_info::float_format float_format (void) const;
00604
00605 static std::string mode_as_string (int mode);
00606
00607 std::istream *input_stream (void)
00608 {
00609 return rep ? rep->input_stream () : 0;
00610 }
00611
00612 std::ostream *output_stream (void)
00613 {
00614 return rep ? rep->output_stream () : 0;
00615 }
00616
00617 void clearerr (void) { if (rep) rep->clearerr (); }
00618
00619 private:
00620
00621
00622 octave_base_stream *rep;
00623
00624 bool stream_ok (bool clear = true) const
00625 {
00626 bool retval = true;
00627
00628 if (rep)
00629 {
00630 if (clear)
00631 rep->clear ();
00632 }
00633 else
00634 retval = false;
00635
00636 return retval;
00637 }
00638
00639 void invalid_operation (const std::string& who, const char *rw)
00640 {
00641 if (rep)
00642 rep->invalid_operation (who, rw);
00643 }
00644 };
00645
00646 class
00647 OCTINTERP_API
00648 octave_stream_list
00649 {
00650 protected:
00651
00652 octave_stream_list (void) : list (), lookup_cache (list.end ()) { }
00653
00654 public:
00655
00656 ~octave_stream_list (void) { }
00657
00658 static bool instance_ok (void);
00659
00660 static int insert (octave_stream& os);
00661
00662 static octave_stream
00663 lookup (int fid, const std::string& who = std::string ());
00664
00665 static octave_stream
00666 lookup (const octave_value& fid, const std::string& who = std::string ());
00667
00668 static int remove (int fid, const std::string& who = std::string ());
00669 static int remove (const octave_value& fid,
00670 const std::string& who = std::string ());
00671
00672 static void clear (bool flush = true);
00673
00674 static string_vector get_info (int fid);
00675 static string_vector get_info (const octave_value& fid);
00676
00677 static std::string list_open_files (void);
00678
00679 static octave_value open_file_numbers (void);
00680
00681 static int get_file_number (const octave_value& fid);
00682
00683 private:
00684
00685 typedef std::map<int, octave_stream> ostrl_map;
00686
00687 ostrl_map list;
00688
00689 mutable ostrl_map::const_iterator lookup_cache;
00690
00691 static octave_stream_list *instance;
00692
00693 static void cleanup_instance (void) { delete instance; instance = 0; }
00694
00695 int do_insert (octave_stream& os);
00696
00697 octave_stream do_lookup (int fid, const std::string& who = std::string ()) const;
00698 octave_stream do_lookup (const octave_value& fid,
00699 const std::string& who = std::string ()) const;
00700
00701 int do_remove (int fid, const std::string& who = std::string ());
00702 int do_remove (const octave_value& fid, const std::string& who = std::string ());
00703
00704 void do_clear (bool flush = true);
00705
00706 string_vector do_get_info (int fid) const;
00707 string_vector do_get_info (const octave_value& fid) const;
00708
00709 std::string do_list_open_files (void) const;
00710
00711 octave_value do_open_file_numbers (void) const;
00712
00713 int do_get_file_number (const octave_value& fid) const;
00714 };
00715
00716 #endif