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