Evo C++ Library v0.5.1
iobase.h
Go to the documentation of this file.
1 // Evo C++ Library
2 /* Copyright 2019 Justin Crowell
3 Distributed under the BSD 2-Clause License -- see included file LICENSE.txt for details.
4 */
6 
7 #pragma once
8 #ifndef INCL_evo_iobase_h
9 #define INCL_evo_iobase_h
10 
11 #include "substring.h"
12 #include "impl/sysio.h"
13 
14 // Namespace: evo
15 namespace evo {
16 
21 
23 
30 struct IoBase : public SafeBool<IoBase> {
33  }
34 
36  virtual ~IoBase() {
37  }
38 
45  bool operator!() const {
46  return (error_ != ENone);
47  }
48 
52  bool excep() const {
53  return excep_;
54  }
55 
59  void excep(bool val) {
60  excep_ = val;
61  }
62 
66  Error error() const {
67  return error_;
68  }
69 
73  virtual bool isopen() const {
74  return false;
75  }
76 
91  virtual ulong readbin(void* buf, ulong size) {
92  EVO_PARAM_UNUSED(buf);
93  EVO_PARAM_UNUSED(size);
94  error_ = ENone;
95  return 0;
96  }
97 
113  virtual ulong writebin(const void* buf, ulong size) {
114  EVO_PARAM_UNUSED(buf);
115  EVO_PARAM_UNUSED(size);
116  error_ = ENotImpl;
117  EVO_THROW_ERR_CHECK(evo::ExceptionStreamOut, "Stream doesn't support writebin()", error_, excep_);
118  return 0;
119  }
120 
127  virtual bool flush() {
128  error_ = ENone;
129  return true;
130  }
131 
132 protected:
134  bool excep_;
135 };
136 
138 
145 struct StreamBase : public IoBase {
146  typedef ulong Size;
147 
150  }
151 
153  virtual ~StreamBase() {
154  }
155 
170  virtual ulong readtext(char* buf, ulong size) {
171  EVO_PARAM_UNUSED(buf);
172  EVO_PARAM_UNUSED(size);
173  error_ = ENone;
174  return 0;
175  }
176 
201  virtual bool readline(String& str, ulong maxlen=0) {
202  EVO_PARAM_UNUSED(str);
203  EVO_PARAM_UNUSED(maxlen);
204  error_ = ENone;
205  return false;
206  }
207 
219  virtual ulong writechar(char ch, ulong count=1) {
220  EVO_PARAM_UNUSED(ch);
221  EVO_PARAM_UNUSED(count);
222  error_ = ENotImpl;
223  EVO_THROW_ERR_CHECK(evo::ExceptionStreamOut, "Stream doesn't support writechar()", error_, excep_);
224  return 0;
225  }
226 
236  virtual ulong writetext(const char* buf, ulong size) {
237  EVO_PARAM_UNUSED(buf);
238  EVO_PARAM_UNUSED(size);
239  error_ = ENotImpl;
240  EVO_THROW_ERR_CHECK(evo::ExceptionStreamOut, "Stream doesn't support writetext()", error_, excep_);
241  return 0;
242  }
243 
254  virtual Size writequoted(const char* buf, Size size, char delim, bool optional=false) {
255  EVO_PARAM_UNUSED(buf);
256  EVO_PARAM_UNUSED(size);
257  EVO_PARAM_UNUSED(delim);
258  EVO_PARAM_UNUSED(optional);
259  error_ = ENotImpl;
260  EVO_THROW_ERR_CHECK(evo::ExceptionStreamOut, "Stream doesn't support writequoted()", error_, excep_);
261  return 0;
262  }
263 
274  virtual ulong writeline(const char* buf, ulong size) {
275  EVO_PARAM_UNUSED(buf);
276  EVO_PARAM_UNUSED(size);
277  error_ = ENotImpl;
278  EVO_THROW_ERR_CHECK(evo::ExceptionStreamOut, "Stream doesn't support writeline()", error_, excep_);
279  return 0;
280  }
281 
290  virtual char* write_direct(Size size) {
291  EVO_PARAM_UNUSED(size);
292  error_ = ENotImpl;
293  EVO_THROW_ERR_CHECK(evo::ExceptionStreamOut, "Stream doesn't support write_direct()", error_, excep_);
294  return NULL;
295  }
296 
307  char* write_direct_multi(Size& available, Size reserve_size) {
308  EVO_PARAM_UNUSED(available);
309  EVO_PARAM_UNUSED(reserve_size);
310  error_ = ENotImpl;
311  EVO_THROW_ERR_CHECK(evo::ExceptionStreamOut, "Stream doesn't support write_direct_multi()", error_, excep_);
312  return NULL;
313  }
314 
325  char* write_direct_flush(Size& available, Size written_size, Size reserve_size) {
326  EVO_PARAM_UNUSED(available);
327  EVO_PARAM_UNUSED(written_size);
328  EVO_PARAM_UNUSED(reserve_size);
329  error_ = ENotImpl;
330  EVO_THROW_ERR_CHECK(evo::ExceptionStreamOut, "Stream doesn't support write_direct_flush()", error_, excep_);
331  return NULL;
332  }
333 
341  virtual bool write_direct_finish(Size size) {
342  EVO_PARAM_UNUSED(size);
343  error_ = ENotImpl;
344  EVO_THROW_ERR_CHECK(evo::ExceptionStreamOut, "Stream doesn't support write_direct_finish()", error_, excep_);
345  return false;
346  }
347 };
348 
350 
405 template<class T>
407  typedef typename T::Size Size;
408  typedef T Out;
410 
411  Out& out;
413 
417  StreamFormatter(Out& out) : out(out) {
418  }
419 
425  StreamFormatter(const This& src) : out(src.out), fmt(src.fmt) {
426  }
427 
434  This& operator=(const This& src) {
435  memcpy(&fmt, &src.fmt, sizeof(FmtAttribs));
436  return *this;
437  }
438 
442  Out& write_out()
443  { return *this; }
444 
445  // Field
446 
451  This& operator<<(FmtAlign align)
452  { fmt.field.align = align; return *this; }
453 
458  This& operator<<(FmtWidth width)
459  { fmt.field.width = width; return *this; }
460 
465  This& operator<<(const FmtSetField& field)
466  { fmt.field.merge(field); return *this; }
467 
468  // Newlines
469 
476  This& operator<<(Newline nl)
477  { out << nl; return *this; }
478 
486  { out << nl; return *this; }
487 
492  This& operator<<(const NewlineValue& nl)
493  { out << nl; return *this; }
494 
501  This& operator<<(Flush) {
502  if (out.error() == ENone)
503  out.flush();
504  return *this;
505  }
506 
507  // Null
508 
513  This& operator<<(const FmtSetNull& null)
514  { fmt.null = null; return *this; }
515 
516  // Bools
517 
525  This& operator<<(bool val) {
526  if (val)
527  out.writetext("true", 4);
528  else
529  out.writetext("false", 5);
530  return *this;
531  }
532 
533  // Chars
534 
539  This& operator<<(char ch) {
540  if (out.error() == ENone)
541  out.writechar(ch, 1);
542  return *this;
543  }
544 
549  This& operator<<(const FmtChar& ch) {
550  if (out.error() == ENone)
551  out.writefmtchar(ch.ch, ch.count, fmt.field);
552  return *this;
553  }
554 
555  // Strings
556 
561  This& operator<<(const FmtString& str) {
562  if (out.error() == ENone) {
563  FmtSetField fmtfield(fmt.field);
564  fmtfield.merge(str.fmt);
565  out.writefmtstr(str.str.data_, str.str.size_, fmtfield);
566  }
567  return *this;
568  }
569 
576  This& operator<<(const char* val) {
577  if (out.error() == ENone) {
578  if (val == NULL) {
579  if (fmt.null.size > 0)
580  out.writefmtstr(fmt.null.str, fmt.null.size, fmt.field);
581  } else if (*val != '\0')
582  out.writefmtstr(val, (ulong)strlen(val), fmt.field);
583  }
584  return *this;
585  }
586 
593  template<class TSize>
594  This& operator<<(const ListBase<char,TSize>& str) {
595  if (out.error() == ENone) {
596  if (str.data_ == NULL) {
597  if (fmt.null.size > 0)
598  out.writefmtstr(fmt.null.str, fmt.null.size, fmt.field);
599  } else if (str.size_ != '\0')
600  out.writefmtstr(str.data_, str.size_, fmt.field);
601  }
602  return *this;
603  }
604 
605  // Integers
606 
611  This& operator<<(FmtBase base)
612  { fmt.num_int.base = base; return *this; }
613 
618  This& operator<<(FmtBasePrefix prefix)
619  { fmt.num_int.prefix = prefix; return *this; }
620 
625  This& operator<<(const FmtSetInt& fmt_int)
626  { fmt.num_int.merge(fmt_int); return *this; }
627 
634  This& operator<<(short num)
635  { out.writefmtnum(num, fmt.num_int, &fmt.field); return *this; }
636 
638  This& operator<<(int num)
639  { out.writefmtnum(num, fmt.num_int, &fmt.field); return *this; }
640 
642  This& operator<<(long num)
643  { out.writefmtnum(num, fmt.num_int, &fmt.field); return *this; }
644 
646  This& operator<<(longl num)
647  { out.writefmtnum(num, fmt.num_int, &fmt.field); return *this; }
648 
655  This& operator<<(ushort num)
656  { out.writefmtnumu(num, fmt.num_int, &fmt.field); return *this; }
657 
659  This& operator<<(uint num)
660  { out.writefmtnumu(num, fmt.num_int, &fmt.field); return *this; }
661 
663  This& operator<<(ulong num)
664  { out.writefmtnumu(num, fmt.num_int, &fmt.field); return *this; }
665 
667  This& operator<<(ulongl num)
668  { out.writefmtnumu(num, fmt.num_int, &fmt.field); return *this; }
669 
678  template<class U>
679  This& operator<<(const IntegerT<U>& num) {
680  if (num.null()) {
681  if (fmt.null.size > 0)
682  out.writefmtstr(fmt.null.str, fmt.null.size, fmt.field);
683  } else if (IntegerT<U>::SIGN)
684  out.writefmtnum(num.value(), fmt.num_int, &fmt.field);
685  else
686  out.writefmtnumu(num.value(), fmt.num_int, &fmt.field);
687  return *this;
688  }
689 
690  // Floats
691 
697  { fmt.num_flt.precision = prec; return *this; }
698 
703  This& operator<<(const FmtSetFloat& fmt_flt)
704  { fmt.num_flt.merge(fmt_flt); return *this; }
705 
712  This& operator<<(float num)
713  { out.writefmtnumf(num, fmt.num_flt, &fmt.field); return *this; }
714 
716  This& operator<<(double num)
717  { out.writefmtnumf(num, fmt.num_flt, &fmt.field); return *this; }
718 
720  This& operator<<(ldouble num)
721  { out.writefmtnumf(num, fmt.num_flt, &fmt.field); return *this; }
722 
730  template<class U>
731  This& operator<<(const FloatT<U>& num) {
732  if (num.null()) {
733  if (fmt.null.size > 0)
734  out.writefmtstr(fmt.null.str, fmt.null.size, fmt.field);
735  } else
736  out.writefmtnumf(num.value(), fmt.num_flt, &fmt.field);
737  return *this;
738  }
739 
740  // Pointer
741 
746  This& operator<<(const FmtPtr& fmtptr)
747  { out.writefmtnumu((ulong)fmtptr.ptr, fmtptr.fmt, &fmt.field); return *this; }
748 
749  // Dump
750 
755  This& operator<<(const FmtDump& fmtdump)
756  { out.writefmtdump(fmtdump); return *this; }
757 };
758 
760 
790 template<class T>
791 class Stream : public StreamBase {
792 public:
793  typedef typename T::Handle Handle;
794  typedef Stream<T> This;
795  typedef This Out;
796 
798 
799  typedef typename T::ExceptionInT ExceptionInT;
800  typedef typename T::ExceptionOutT ExceptionOutT;
801 
805  Stream(Newline newlines=NL_SYS) :
806  owned_(false),
807  bufrd_(0, newlines),
808  bufwr_(0, newlines),
809  savepos_(0),
810  rwlast_(rwlNONE)
811  { }
812 
818  close();
819  }
820 
824  Handle handle() const {
825  return device_.handle;
826  }
827 
836  return bufrd_.readbuf;
837  }
838 
847  return bufwr_;
848  }
849 
856  void attach(Open mode, Handle handle, bool owned=true, bool flushlines=false) {
857  close();
858  device_.handle = handle;
859  if (device_.isopen()) {
860  init(mode, flushlines);
861  owned_ = owned;
862  }
863  }
864 
871  Handle detach() {
872  if (device_.isopen()) {
873  if (bufwr_.used > 0)
874  bufwr_.flush(device_);
875  bufrd_.close();
876  bufwr_.close();
877  owned_ = false;
878  }
879  return device_.detach();
880  }
881 
888  bool close() {
889  if (device_.isopen()) {
890  if (bufwr_.used > 0) {
891  error_ = bufwr_.flush(device_);
892  } else
893  error_ = ENone;
894  bufrd_.close();
895  bufwr_.close();
896  if (owned_) {
897  device_.close();
898  owned_ = false;
899  } else
900  device_.detach();
901  return (error_ == ENone);
902  }
903  return true;
904  }
905 
906  bool isopen() const {
907  return device_.isopen();
908  }
909 
910  ulong readbin(void* buf, ulong size) {
911  if (T::STREAM_SEEKABLE && rwlast_ != rwlREAD && !readprep())
912  return 0;
913  size = bufrd_.readbin(error_, device_, buf, size);
914  EVO_THROW_ERR_CHECK(ExceptionInT, "Stream binary read failed", error_, (excep_ && size == 0 && error_ != ENone && error_ != EEnd));
915  return size;
916  }
917 
918  ulong readtext(char* buf, ulong size) {
919  if (T::STREAM_SEEKABLE && rwlast_ != rwlREAD && !readprep())
920  return 0;
921  size = bufrd_.readtext(error_, device_, buf, size);
922  EVO_THROW_ERR_CHECK(ExceptionInT, "Stream text read failed", error_, (excep_ && size == 0 && error_ != ENone && error_ != EEnd));
923  return size;
924  }
925 
926  bool readline(String& str, ulong maxlen=0) {
927  if (T::STREAM_SEEKABLE && rwlast_ != rwlREAD && !readprep())
928  return false;
929  error_ = bufrd_.readline(str, device_, maxlen);
930  if (error_ != ENone && error_ != EEnd) {
931  EVO_THROW_ERR_CHECK(ExceptionInT, "Stream text line read failed", error_, excep_);
932  return false;
933  }
934  return true;
935  }
936 
937  bool flush() {
938  error_ = bufwr_.flush(device_);
939  if (error_ != ENone) {
940  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream flush failed", error_, excep_);
941  return false;
942  }
943  return true;
944  }
945 
946  ulong writebin(const void* buf, ulong size) {
947  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
948  return 0;
949  size = bufwr_.writebin(error_, device_, buf, size);
950  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream binary write failed", error_, (excep_ && size == 0 && error_ != ENone));
951  return size;
952  }
953 
954  ulong writechar(char ch, ulong count=1) {
955  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
956  return 0;
957  count = bufwr_.writetext_char(error_, device_, ch, count);
958  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write failed", error_, (excep_ && count == 0 && error_ != ENone));
959  return count;
960  }
961 
962  ulong writetext(const char* buf, ulong size) {
963  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
964  return 0;
965  size = bufwr_.writetext(error_, device_, buf, size);
966  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write failed", error_, (excep_ && size == 0 && error_ != ENone));
967  return size;
968  }
969 
970  Size writequoted(const char* buf, Size size, char delim, bool optional=false) {
971  bool quote_optional = false;
972  const StrQuoting::Type type = StrQuoting::get(quote_optional, buf, size, delim);
973  switch (type) {
974  case StrQuoting::tSINGLE:
975  if (quote_optional && optional)
976  return writebin(buf, size);
977  case StrQuoting::tDOUBLE:
978  case StrQuoting::tBACKTICK: {
979  const char ch = "'\"`"[(uint)type];
980  const Size result = size + 2;
981  if (writebin(&ch, 1) == 1 && writebin(buf, size) == size && writebin(&ch, 1) == 1)
982  return result;
983  break;
984  }
987  case StrQuoting::tBACKTICK3: {
988  const char* str = &"'''\"\"\"```"[(uint(type) - 3) * 3];
989  const Size result = size + 6;
990  if (writebin(str, 3) == 3 && writebin(buf, size) == size && writebin(str, 3) == 3)
991  return result;
992  break;
993  }
995  const char* str = "`\x7F";
996  const Size result = size + 4;
997  if (writebin(str, 2) != 2 || writebin(buf, size) != size || writebin(str, 2) != 2)
998  return result;
999  break;
1000  }
1001  case StrQuoting::tERROR:
1002  error_ = EInval;
1003  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write failed on unquotable text", error_, excep_);
1004  break;
1005  }
1006  return 0;
1007  }
1008 
1009  ulong writeline(const char* buf, ulong size) {
1010  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1011  return 0;
1012  ulong writtensize = bufwr_.writetext(error_, device_, buf, size), writtensize2;
1013  bufwr_.partnl = 0;
1014  if ( writtensize == 0 || (writtensize2=bufwr_.writebin(error_, device_, bufwr_.newline, bufwr_.newlinesize)) == 0 ) {
1015  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text line write failed", error_, excep_);
1016  return 0;
1017  }
1018  return writtensize + writtensize2;
1019  }
1020 
1021  Out& write_out()
1022  { return *this; }
1023 
1024  char* write_direct(Size size) {
1025  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1026  return 0;
1027  if (size > bufwr_.size) {
1028  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream not large enough for write_direct()", error_, excep_);
1029  return NULL;
1030  }
1031  if (bufwr_.avail() < size) {
1032  error_ = bufwr_.flush(device_);
1033  if (error_ != ENone) {
1034  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream flush failed", error_, excep_);
1035  return NULL;
1036  }
1037  }
1038  bufwr_.partnl = 0;
1039  return bufwr_.data + bufwr_.used;
1040  }
1041 
1042  char* write_direct_multi(Size& available, Size reserve_size) {
1043  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1044  return 0;
1045  if (reserve_size > bufwr_.avail()) {
1046  error_ = bufwr_.flush(device_);
1047  if (error_ != ENone) {
1048  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream flush failed", error_, excep_);
1049  return NULL;
1050  }
1051  if (reserve_size > bufwr_.size)
1052  available = (Size)bufwr_.size;
1053  else
1054  available = reserve_size;
1055  } else {
1056  available = reserve_size;
1057  if (reserve_size == 0)
1058  return (char*)1; // finished
1059  }
1060  bufwr_.partnl = 0;
1061  return bufwr_.data + bufwr_.used;
1062  }
1063 
1064  char* write_direct_flush(Size& available, Size written_size, Size reserve_size) {
1065  bufwr_.used += written_size;
1066  assert( bufwr_.used <= bufwr_.size );
1067 
1068  error_ = bufwr_.flush(device_);
1069  if (error_ != ENone) {
1070  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream flush failed", error_, excep_);
1071  return NULL;
1072  }
1073 
1074  if (reserve_size > bufwr_.size) {
1075  available = (Size)bufwr_.size;
1076  } else {
1077  available = reserve_size;
1078  if (reserve_size == 0)
1079  return (char*)1; // finished
1080  }
1081 
1082  return bufwr_.data;
1083  }
1084 
1086  bufwr_.used += size;
1087  assert( bufwr_.used <= bufwr_.size );
1088  return true;
1089  }
1090 
1100  template<class TNum>
1101  bool writenum(TNum num, int base=fDEC) {
1102  if (error_ == ENone) {
1103  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1104  return false;
1105  error_ = bufwr_.writenum(device_, num, base);
1106  if (error_ != ENone) {
1107  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write number failed", error_, excep_);
1108  return false;
1109  }
1110  return true;
1111  }
1112  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write number blocked by previous error", error_, excep_);
1113  return false;
1114  }
1115 
1125  template<class TNum>
1126  bool writenumu(TNum num, int base=fDEC) {
1127  if (error_ == ENone) {
1128  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1129  return false;
1130  error_ = bufwr_.writenumu(device_, num, base);
1131  if (error_ != ENone) {
1132  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write number failed", error_, excep_);
1133  return false;
1134  }
1135  return true;
1136  }
1137  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write number blocked by previous error", error_, excep_);
1138  return false;
1139  }
1140 
1150  template<class TNum>
1151  bool writenumf(TNum num, int precision=fPREC_AUTO) {
1152  if (error_ == ENone) {
1153  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1154  return false;
1155  error_ = bufwr_.writenumf(device_, num, precision);
1156  if (error_ != ENone) {
1157  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write number failed", error_, excep_);
1158  return false;
1159  }
1160  return true;
1161  }
1162  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write number blocked by previous error", error_, excep_);
1163  return false;
1164  }
1165 
1172  bool writefmtchar(char ch, ulong count, const FmtSetField& field) {
1173  if (error_ == ENone) {
1174  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1175  return false;
1176  error_ = bufwr_.writefmtchar(device_, ch, count, field);
1177  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text formatted write char failed", error_, (excep_ && error_ != ENone));
1178  return true;
1179  }
1180  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write formatted char blocked by previous error", error_, excep_);
1181  return false;
1182  }
1183 
1194  bool writefmtstr(const char* buf, ulong size, const FmtSetField& field) {
1195  if (error_ == ENone) {
1196  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1197  return false;
1198  error_ = bufwr_.writefmtstr(device_, buf, size, field);
1199  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text formatted write string failed", error_, (excep_ && error_ != ENone));
1200  return true;
1201  }
1202  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write formatted string blocked by previous error", error_, excep_);
1203  return false;
1204  }
1205 
1216  template<class TNum>
1217  bool writefmtnum(TNum num, const FmtSetInt& fmt, const FmtSetField* field=NULL) {
1218  if (error_ == ENone) {
1219  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1220  return false;
1221  error_ = bufwr_.writefmtnum(device_, num, fmt, field);
1222  if (error_ != ENone) {
1223  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write formatted number failed", error_, excep_);
1224  return false;
1225  }
1226  return true;
1227  }
1228  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write formatted number blocked by previous error", error_, excep_);
1229  return false;
1230  }
1231 
1242  template<class TNum>
1243  bool writefmtnumu(TNum num, const FmtSetInt& fmt, const FmtSetField* field=NULL) {
1244  if (error_ == ENone) {
1245  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1246  return false;
1247  error_ = bufwr_.writefmtnumu(device_, num, fmt, field);
1248  if (error_ != ENone) {
1249  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write formatted number failed", error_, excep_);
1250  return false;
1251  }
1252  return true;
1253  }
1254  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write formatted number blocked by previous error", error_, excep_);
1255  return false;
1256  }
1257 
1268  template<class TNum>
1269  bool writefmtnumf(TNum num, const FmtSetFloat& fmt, const FmtSetField* field=NULL) {
1270  if (error_ == ENone) {
1271  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1272  return false;
1273  error_ = bufwr_.writefmtnumf(device_, num, fmt, field);
1274  if (error_ != ENone) {
1275  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write formatted number failed", error_, excep_);
1276  return false;
1277  }
1278  return true;
1279  }
1280  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write formatted number blocked by previous error", error_, excep_);
1281  return false;
1282  }
1283 
1292  bool writefmtdump(const FmtDump& fmt) {
1293  if (error_ == ENone) {
1294  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1295  return false;
1296  error_ = bufwr_.writefmtdump(device_, fmt, bufwr_.newline, bufwr_.newlinesize);
1297  if (error_ != ENone) {
1298  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write hex dump failed", error_, excep_);
1299  return false;
1300  }
1301  return true;
1302  }
1303  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write hex dump blocked by previous error", error_, excep_);
1304  return false;
1305  }
1306 
1316  bool writefmtdump(const FmtDump& fmt, Newline nl) {
1317  if (error_ == ENone) {
1318  if (T::STREAM_SEEKABLE && rwlast_ != rwlWRITE && !writeprep())
1319  return false;
1320  error_ = bufwr_.writefmtdump(device_, fmt, getnewline(nl), getnewlinesize(nl));
1321  if (error_ != ENone) {
1322  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write hex dump failed", error_, excep_);
1323  return false;
1324  }
1325  return true;
1326  }
1327  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream text write hex dump blocked by previous error", error_, excep_);
1328  return false;
1329  }
1330 
1334  This& operator<<(This&)
1335  { return *this; }
1336 
1343  This& operator<<(Newline nl) {
1344  if (error_ == ENone) {
1346  flush();
1347  }
1348  return *this;
1349  }
1350 
1358  EVO_PARAM_UNUSED(nl);
1359  if (error_ == ENone) {
1360  writebin(bufwr_.newline, bufwr_.newlinesize);
1361  flush();
1362  }
1363  return *this;
1364  }
1365 
1370  This& operator<<(const NewlineValue& nl) {
1371  if (error_ == ENone) {
1372  uint nl_size;
1373  const char* nl_str = nl.getnewline(nl_size, bufwr_.newline, bufwr_.newlinesize);
1374  writebin(nl_str, nl_size);
1375  flush();
1376  }
1377  return *this;
1378  }
1379 
1387  if (error_ == ENone)
1388  flush();
1389  return *this;
1390  }
1391 
1399  This& operator<<(bool val) {
1400  if (error_ == ENone) {
1401  if (val)
1402  bufwr_.writetext(error_, device_, "true", 4);
1403  else
1404  bufwr_.writetext(error_, device_, "false", 5);
1405  }
1406  return *this;
1407  }
1408 
1415  This& operator<<(char ch) {
1416  if (error_ == ENone)
1417  writechar(ch);
1418  return *this;
1419  }
1420 
1427  This& operator<<(const char* str) {
1428  if (error_ == ENone && str != NULL)
1429  writetext(str, (ulong)strlen(str));
1430  return *this;
1431  }
1432 
1439  This& operator<<(const SubString& str) {
1440  if (error_ == ENone && str.size_ > 0)
1441  writetext(str.data_, str.size_);
1442  return *this;
1443  }
1444 
1454  template<class TSize>
1455  This& operator<<(const ListBase<char,TSize>& str) {
1456  if (error_ == ENone && str.size_ > 0)
1457  writetext(str.data_, str.size_);
1458  return *this;
1459  }
1460 
1468  This& operator<<(int num)
1469  { writenum(num); return *this; }
1470 
1478  This& operator<<(long num)
1479  { writenum(num); return *this; }
1480 
1488  This& operator<<(longl num)
1489  { writenum(num); return *this; }
1490 
1498  This& operator<<(uint num)
1499  { writenumu(num); return *this; }
1500 
1508  This& operator<<(ulong num)
1509  { writenumu(num); return *this; }
1510 
1518  This& operator<<(ulongl num)
1519  { writenumu(num); return *this; }
1520 
1530  template<class U>
1531  This& operator<<(const IntegerT<U>& num) {
1532  if (!num.null())
1533  writenum(num.value());
1534  return *this;
1535  }
1536 
1544  This& operator<<(float num)
1545  { writenumf(num); return *this; }
1546 
1554  This& operator<<(double num)
1555  { writenumf(num); return *this; }
1556 
1564  This& operator<<(ldouble num)
1565  { writenumf(num); return *this; }
1566 
1576  template<class U>
1577  This& operator<<(const FloatT<U>& num) {
1578  if (!num.null())
1579  writenumf(num.value());
1580  return *this;
1581  }
1582 
1590  This& operator<<(const FmtChar& fmt)
1591  { writechar(fmt.ch, fmt.count); return *this; }
1592 
1597  This& operator<<(const FmtString& fmt)
1598  { writefmtstr(fmt.str.data_, fmt.str.size_, fmt.fmt); return *this; }
1599 
1607  This& operator<<(const FmtShort& fmt)
1608  { writefmtnum(fmt.num, fmt.fmt); return *this; }
1609 
1611  This& operator<<(const FmtInt& fmt)
1612  { writefmtnum(fmt.num, fmt.fmt); return *this; }
1613 
1615  This& operator<<(const FmtLong& fmt)
1616  { writefmtnum(fmt.num, fmt.fmt); return *this; }
1617 
1619  This& operator<<(const FmtLongL& fmt)
1620  { writefmtnum(fmt.num, fmt.fmt); return *this; }
1621 
1623  This& operator<<(const FmtUShort& fmt)
1624  { writefmtnumu(fmt.num, fmt.fmt); return *this; }
1625 
1627  This& operator<<(const FmtUInt& fmt)
1628  { writefmtnumu(fmt.num, fmt.fmt); return *this; }
1629 
1631  This& operator<<(const FmtULong& fmt)
1632  { writefmtnumu(fmt.num, fmt.fmt); return *this; }
1633 
1635  This& operator<<(const FmtULongL& fmt)
1636  { writefmtnumu(fmt.num, fmt.fmt); return *this; }
1637 
1639  This& operator<<(const FmtFloat& fmt)
1640  { writefmtnumf(fmt.num, fmt.fmt); return *this; }
1641 
1643  This& operator<<(const FmtFloatD& fmt)
1644  { writefmtnumf(fmt.num, fmt.fmt); return *this; }
1645 
1647  This& operator<<(const FmtFloatL& fmt)
1648  { writefmtnumf(fmt.num, fmt.fmt); return *this; }
1649 
1651  template<class U>
1652  This& operator<<(const FmtFieldNum<U>& fmt) {
1653  if (IntegerT<U>::SIGN)
1654  writefmtnum(fmt.num.num, fmt.num.fmt, &fmt.field);
1655  else
1656  writefmtnumu(fmt.num.num, fmt.num.fmt, &fmt.field);
1657  return *this;
1658  }
1659 
1661  template<class U>
1662  This& operator<<(const FmtFieldFloat<U>& fmt)
1663  { writefmtnumf(fmt.num.num, fmt.num.fmt, &fmt.field); return *this; }
1664 
1669  This& operator<<(const FmtPtr& fmtptr)
1670  { writefmtnumu((ulong)fmtptr.ptr, fmtptr.fmt); return *this; }
1671 
1676  This& operator<<(const FmtDump& fmt)
1677  { writefmtdump(fmt); return *this; }
1678 
1679 protected:
1681  enum RwLast {
1682  rwlNONE = 0,
1684  rwlWRITE
1685  };
1686 
1688  bool owned_;
1691  ulongl savepos_;
1692  RwLast rwlast_;
1693 
1695  void init(Open mode, bool flushlines=false) {
1696  savepos_ = 0;
1697  rwlast_ = rwlNONE;
1698  if (open_readable(mode))
1699  bufrd_.open();
1700  if (open_writable(mode))
1701  bufwr_.open(flushlines);
1702  }
1703 
1704 private:
1705  Stream(const This&);
1706  This& operator=(const This&);
1707 
1708  // Restore buffered read position (switching from write to read)
1709  bool readprep() {
1710  if (rwlast_ != rwlNONE) {
1711  if ((error_=bufwr_.flush(device_)) != ENone) {
1712  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream flush failed before switch to read mode", error_, excep_);
1713  return false;
1714  }
1715  ulongl newpos = device_.pos(error_);
1716  if (error_ != ENone) {
1717  EVO_THROW_ERR_CHECK(ExceptionInT, "Stream position read failed during switch to read mode", error_, excep_);
1718  return false;
1719  }
1720  if (newpos > savepos_ || bufrd_.readbuf.used > savepos_ || newpos < savepos_-bufrd_.readbuf.used) {
1721  bufrd_.readbuf.used = bufrd_.curbuf_offset = 0; // seeking outside buffered data
1722  device_.seek(error_, newpos, sBegin);
1723  } else {
1724  bufrd_.curbuf_offset = bufrd_.readbuf.used - (ulong)(savepos_ - newpos);
1725  device_.seek(error_, savepos_, sBegin);
1726  }
1727  if (error_ != ENone) {
1728  EVO_THROW_ERR_CHECK(ExceptionInT, "Stream seek failed during switch to read mode", error_, excep_);
1729  return false;
1730  }
1731  savepos_ = 0;
1732  }
1733  rwlast_ = rwlREAD;
1734  return true;
1735  }
1736 
1737  // Save buffered read position (switching from read to write)
1738  bool writeprep() {
1739  if (rwlast_ != rwlNONE) {
1740  savepos_ = device_.pos(error_);
1741  if (error_ != ENone) {
1742  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream position read failed during switch to write mode", error_, excep_);
1743  return false;
1744  }
1745  device_.seek(error_, savepos_-(bufrd_.readbuf.used-bufrd_.curbuf_offset), sBegin);
1746  if (error_ != ENone) {
1747  EVO_THROW_ERR_CHECK(ExceptionOutT, "Stream seek failed during switch to write mode", error_, excep_);
1748  return false;
1749  }
1750  }
1751  rwlast_ = rwlWRITE;
1752  return true;
1753  }
1754 };
1755 
1757 
1758 }
1759 #endif
This & operator<<(const FmtSetFloat &fmt_flt)
Set floating point formatting attributes.
Definition: iobase.h:703
This & operator<<(const FmtSetInt &fmt_int)
Set integer formatting attributes.
Definition: iobase.h:625
This & operator<<(const SubString &str)
Write substring to stream.
Definition: iobase.h:1439
void init(Open mode, bool flushlines=false)
Initialize and reset buffers for a new stream.
Definition: iobase.h:1695
void open(bool flushlines_val=false)
Initialize and open for output (writing).
Definition: sysio.h:1051
This & operator<<(const FmtSetField &field)
Set field attributes to use.
Definition: iobase.h:465
This & operator<<(longl num)
Append a formatted signed integer.
Definition: iobase.h:646
void excep(bool val)
Set whether exceptions are enabled.
Definition: iobase.h:59
This & operator<<(const NewlineValue &nl)
Write newline value and flush stream.
Definition: iobase.h:492
const char * getnewline(Newline newline=NL)
Get newline string for given type.
Definition: sys.h:793
This & operator<<(ldouble num)
Write formatted floating-point number to stream.
Definition: iobase.h:1564
virtual ulong writetext(const char *buf, ulong size)
Write text output to stream.
Definition: iobase.h:236
This & operator<<(const FmtFloat &fmt)
Write formatted number field to stream.
Definition: iobase.h:1639
This & operator<<(const FmtULong &fmt)
Write formatted number field to stream.
Definition: iobase.h:1631
This & operator<<(ulongl num)
Write formatted number to stream.
Definition: iobase.h:1518
Holds integer formatting attributes.
Definition: str.h:2589
This & operator<<(const FmtInt &fmt)
Write formatted number field to stream.
Definition: iobase.h:1611
This & operator<<(const FmtPtr &fmtptr)
Writer formatted pointer field to stream.
Definition: iobase.h:746
Holds a Newline value that can be null, which implicitly converts to NL_SYS (system default newline)...
Definition: sys.h:813
This & operator<<(Newline nl)
Write an explicit newline and flush stream.
Definition: iobase.h:1343
Evo SubString container.
This & operator<<(FmtBase base)
Set base for formatting integers.
Definition: iobase.h:611
Invalid argument or data.
Definition: sys.h:1123
This & operator<<(bool val)
Append a bool value to stream.
Definition: iobase.h:1399
ulong readtext(char *buf, ulong size)
Read text input from stream.
Definition: iobase.h:918
bool excep() const
Get whether exceptions are enabled.
Definition: iobase.h:52
bool open_writable(Open open)
Check whether open mode is writable.
Definition: sysio.h:220
Formatting attributes (used internally).
Definition: str.h:2886
bool writefmtdump(const FmtDump &fmt)
Write formatted data dump.
Definition: iobase.h:1292
This & operator<<(uint num)
Append a formatted unsigned integer.
Definition: iobase.h:659
This & operator<<(NewlineDefault nl)
Write default newline and flush stream.
Definition: iobase.h:1357
Single-quotes: &#39;
Definition: strscan.h:1898
This & operator=(const This &src)
Assignment operator copies attributes.
Definition: iobase.h:434
virtual ~StreamBase()
Destructor.
Definition: iobase.h:153
Error error_
Last error code.
Definition: iobase.h:133
This & operator<<(longl num)
Write formatted number to stream.
Definition: iobase.h:1488
Automatic floating point precision – either normal decimal notation or E notation, whichever is shorter (default)
Definition: str.h:2343
This & operator<<(Flush)
Flush buffer by writing to stream.
Definition: iobase.h:1386
bool writenum(TNum num, int base=fDEC)
Write formatted signed number.
Definition: iobase.h:1101
virtual ulong readtext(char *buf, ulong size)
Read text input from stream.
Definition: iobase.h:170
Backtick: `
Definition: strscan.h:1900
Holds string to use when formatting null values.
Definition: str.h:2406
Triple backtick: ```
Definition: strscan.h:1903
Triple single-quotes: &#39;&#39;&#39;
Definition: strscan.h:1901
Out & out
Associated output stream.
Definition: iobase.h:411
This & operator<<(const FmtULongL &fmt)
Write formatted number field to stream.
Definition: iobase.h:1635
virtual bool flush()
Flush any pending output in stream write buffer, if buffered.
Definition: iobase.h:127
char * write_direct_flush(Size &available, Size written_size, Size reserve_size)
Definition: iobase.h:1064
uint count
Character repeat count.
Definition: str.h:2916
Open
Open mode for files and streams.
Definition: sysio.h:190
bool excep_
Whether to throw exceptions.
Definition: iobase.h:134
bool open_readable(Open open)
Check whether open mode is readable.
Definition: sysio.h:213
ulong writechar(char ch, ulong count=1)
Write repeat character as text output to stream.
Definition: iobase.h:954
bool write_direct_finish(Size size)
Finish writing directly to buffer.
Definition: iobase.h:1085
Base text and binary stream interface.
Definition: iobase.h:145
Output stream exception for stream write errors, see Exception.
Definition: sys.h:1401
Newline
Newline type.
Definition: sys.h:748
virtual bool isopen() const
Get whether stream is open.
Definition: iobase.h:73
#define EVO_THROW_ERR_CHECK(TYPE, MSG, ERROR, COND)
Throw an Evo exception with error code if COND is true.
Definition: sys.h:1513
T device_
I/O device.
Definition: iobase.h:1687
bool writefmtstr(const char *buf, ulong size, const FmtSetField &field)
Write text with field alignment.
Definition: iobase.h:1194
virtual ulong writechar(char ch, ulong count=1)
Write repeat character as text output to stream.
Definition: iobase.h:219
void open()
Initialize and open for input (reading).
Definition: sysio.h:690
This & operator<<(ulong num)
Append a formatted unsigned integer.
Definition: iobase.h:663
This & operator<<(ushort num)
Append a formatted unsigned integer.
Definition: iobase.h:655
RawBuffer & bufread()
Advanced: Access primary read buffer.
Definition: iobase.h:835
ulong readbin(void *buf, ulong size)
Read binary input from stream.
Definition: iobase.h:910
char * write_direct(Size size)
Get pointer for writing directly to buffer to append data.
Definition: iobase.h:1024
This & operator<<(short num)
Append a formatted signed integer.
Definition: iobase.h:634
Basic integer type.
Definition: type.h:980
~Stream()
Destructor.
Definition: iobase.h:817
FmtSetFloat fmt
Definition: str.h:3156
ulong writetext(const char *buf, ulong size)
Write text output to stream.
Definition: iobase.h:962
IoWriter bufwr_
Buffered writer.
Definition: iobase.h:1690
virtual bool readline(String &str, ulong maxlen=0)
Read text line input from stream.
Definition: iobase.h:201
bool operator!() const
Negation operator checks whether an error was set by a previous operation.
Definition: iobase.h:45
No error.
Definition: sys.h:1115
Reached end of resource (not an error)
Definition: sys.h:1116
#define EVO_EXCEPTIONS
Whether to throw exceptions on error by default.
Definition: evo_config.h:35
IoBase()
Constructor.
Definition: iobase.h:32
virtual ulong writebin(const void *buf, ulong size)
Write binary output to stream.
Definition: iobase.h:113
This Out
Type returned by write_out()
Definition: iobase.h:795
Error
General Evo error code stored in exceptions, or used directly when exceptions are disabled...
Definition: sys.h:1113
uint getnewlinesize(Newline newline=NL)
Get newline string size for given type.
Definition: sys.h:804
FmtAlign
Formatting alignment.
Definition: str.h:2356
This & operator<<(const FmtUShort &fmt)
Write formatted number field to stream.
Definition: iobase.h:1623
bool close()
Close stream.
Definition: iobase.h:888
This & operator<<(const char *str)
Write terminated string to stream.
Definition: iobase.h:1427
Seek from beginning.
Definition: sysio.h:204
This & operator<<(const FmtChar &fmt)
Write repeated character to stream.
Definition: iobase.h:1590
Base 10: decimal (default)
Definition: str.h:2323
ulong writeline(const char *buf, ulong size)
Write text line output to stream.
Definition: iobase.h:1009
This & operator<<(const char *val)
Append a terminated string.
Definition: iobase.h:576
String container.
Definition: string.h:674
This & operator<<(const FmtChar &ch)
Append a repeated character.
Definition: iobase.h:549
Safe bool base class.
Definition: type.h:73
Buffered reader for IoDevice (used internally).
Definition: sysio.h:658
Flush
Signals an output stream to flush pending data.
Definition: sys.h:739
This & operator<<(const FmtSetNull &null)
Set attributes for null values.
Definition: iobase.h:513
This & operator<<(bool val)
Append a bool value.
Definition: iobase.h:525
This & operator<<(const FmtShort &fmt)
Write formatted number field to stream.
Definition: iobase.h:1607
This & operator<<(const FmtLongL &fmt)
Write formatted number field to stream.
Definition: iobase.h:1619
Evo system I/O implementation.
bool writefmtnumu(TNum num, const FmtSetInt &fmt, const FmtSetField *field=NULL)
Write formatted unsigned number with field alignment.
Definition: iobase.h:1243
StreamFormatter(const This &src)
Copy constructor.
Definition: iobase.h:425
This & operator<<(ulongl num)
Append a formatted unsigned integer.
Definition: iobase.h:667
Stream output formatter with state.
Definition: iobase.h:406
Base binary stream interface.
Definition: iobase.h:30
virtual Size writequoted(const char *buf, Size size, char delim, bool optional=false)
Write quoted text output to string.
Definition: iobase.h:254
void merge(const FmtSetInt &src)
Merge source attributes (used internally).
Definition: str.h:2626
const char * str
Pointer to string for formatting null values, ignored if size is 0.
Definition: str.h:2407
RawBuffer readbuf
Primary read buffer – filtering may involve additional buffers.
Definition: sysio.h:661
bool writenumf(TNum num, int precision=fPREC_AUTO)
Write formatted floating-point number.
Definition: iobase.h:1151
bool writefmtdump(const FmtDump &fmt, Newline nl)
Write formatted data dump with explicit newline type.
Definition: iobase.h:1316
void merge(const FmtSetField &src)
Merge source attributes (used internally).
Definition: str.h:2514
Explicitly format an integer.
Definition: str.h:3065
StreamFormatter< This > Format
Stream output formatter with state.
Definition: iobase.h:797
const char * getnewline() const
Get newline string pointer for current value.
Definition: sys.h:885
ulong writebin(const void *buf, ulong size)
Write binary output to stream.
Definition: iobase.h:946
FmtAlign align
Field alignment type (default: fLEFT)
Definition: str.h:2482
virtual ~IoBase()
Destructor.
Definition: iobase.h:36
T::Handle Handle
Low-level handle type (OS dependent)
Definition: iobase.h:793
Error flush(T &out)
Flush buffer by writing to device.
Definition: sysio.h:1071
FmtPrecision
Formatting floating point precision type.
Definition: str.h:2341
This & operator<<(const FmtLong &fmt)
Write formatted number field to stream.
Definition: iobase.h:1615
StreamFormatter< T > This
This type.
Definition: iobase.h:409
FmtSetInt fmt
Formatting attributes.
Definition: str.h:3266
ulong Size
Data size type (ulong)
Definition: iobase.h:146
This & operator<<(ldouble num)
Append a formatting floating point number.
Definition: iobase.h:720
Handle detach()
Detach current stream.
Definition: iobase.h:871
Double-quotes: "
Definition: strscan.h:1899
void merge(const FmtSetFloat &src)
Merge from source (used internally).
Definition: str.h:2806
Definition: iobase.h:1683
StreamFormatter(Out &out)
Constructor.
Definition: iobase.h:417
Triple double-quotes: """
Definition: strscan.h:1902
Evo C++ Library namespace.
Definition: alg.h:11
Stream(Newline newlines=NL_SYS)
Constructor.
Definition: iobase.h:805
void attach(Open mode, Handle handle, bool owned=true, bool flushlines=false)
Attach existing stream.
Definition: iobase.h:856
Stream< T > This
This stream type.
Definition: iobase.h:794
FmtAttribs fmt
Formatting attributes (state)
Definition: iobase.h:412
Holds floating point formatting attributes.
Definition: str.h:2775
RwLast rwlast_
Read/Write: Used to track last operation when switching between read/write.
Definition: iobase.h:1692
This & operator<<(uint num)
Write formatted number to stream.
Definition: iobase.h:1498
Explicitly format a string.
Definition: str.h:2931
bool writenumu(TNum num, int base=fDEC)
Write formatted unsigned number.
Definition: iobase.h:1126
This & operator<<(int num)
Write formatted number to stream.
Definition: iobase.h:1468
Out & write_out()
Definition: iobase.h:1021
virtual ulong readbin(void *buf, ulong size)
Read binary input from stream.
Definition: iobase.h:91
Input/Output stream implementation.
Definition: iobase.h:791
This & operator<<(const FmtString &str)
Append a formatted string.
Definition: iobase.h:561
T num
Definition: str.h:3155
FmtSetInt fmt
Formatting attributes.
Definition: str.h:3072
virtual ulong writeline(const char *buf, ulong size)
Write text line output to stream.
Definition: iobase.h:274
T::Size Size
Data size type (ulong)
Definition: iobase.h:407
int precision
Floating point precision (number of digits after decimal), fPREC_AUTO for automatic (default: fPREC_A...
Definition: str.h:2776
Handle handle() const
Get stream handle for low-level calls.
Definition: iobase.h:824
static const Newline NL_SYS
Current system newline type.
Definition: sys.h:763
This & operator<<(FmtBasePrefix prefix)
Set prefix for formatting integers.
Definition: iobase.h:618
This & operator<<(Flush)
Flush buffer by writing to stream.
Definition: iobase.h:501
Buffered writer for IoDevice (used internally).
Definition: sysio.h:1023
T * data_
Data pointer, NULL if null.
Definition: sys.h:979
This & operator<<(float num)
Write formatted floating-point number to stream.
Definition: iobase.h:1544
Backtick followed by DEL char (7F) – last resort (rare)
Definition: strscan.h:1904
This & operator<<(float num)
Append a formatting floating point number.
Definition: iobase.h:712
Explicitly format a repeated character.
Definition: str.h:2914
Out & write_out()
Get parent output string.
Definition: iobase.h:442
bool writefmtchar(char ch, ulong count, const FmtSetField &field)
Write formatted and/or repeated character.
Definition: iobase.h:1172
Error error() const
Get error code from last operation.
Definition: iobase.h:66
This & operator<<(int num)
Append a formatted signed integer.
Definition: iobase.h:638
T::ExceptionOutT ExceptionOutT
Stream output exception type
Definition: iobase.h:800
This & operator<<(const FmtFloatD &fmt)
Write formatted number field to stream.
Definition: iobase.h:1643
bool owned_
Whether handle is owned (to be closed here)
Definition: iobase.h:1688
int base
Base for formatting (default: fDEC)
Definition: str.h:2590
Default newline type, implicitly converts to NL_SYS (system default newline).
Definition: sys.h:773
This & operator<<(const NewlineValue &nl)
Write newline value and flush stream.
Definition: iobase.h:1370
Explicitly format a pointer.
Definition: str.h:3264
FmtWidth
Formatting field width.
Definition: str.h:2367
ulong curbuf_offset
Bytes read from curbuf, i.e. buffer start offset.
Definition: sysio.h:663
StrSizeT size
String (str) size for formatting null values, 0 for none/empty
Definition: str.h:2408
This & operator<<(const FmtDump &fmt)
Write formatted data dump to stream.
Definition: iobase.h:1676
This & operator<<(const FmtString &fmt)
Write formatted string field to stream.
Definition: iobase.h:1597
FmtSetField field
Field alignment attributes.
Definition: str.h:2890
This & operator<<(char ch)
Write character to stream.
Definition: iobase.h:1415
char * write_direct_multi(Size &available, Size reserve_size)
Definition: iobase.h:1042
static Type get(const char *data, ulong data_size)
Definition: strscan.h:1917
T Out
Associated output stream type, type returned by write_out()
Definition: iobase.h:408
FmtBasePrefix prefix
Formatting prefix type (default: fPREFIX0)
Definition: str.h:2591
This & operator<<(Newline nl)
Write an explicit newline and flush stream.
Definition: iobase.h:476
This & operator<<(FmtAlign align)
Set field alignment type to use.
Definition: iobase.h:451
TSize size_
Data size as item count, 0 if empty or null.
Definition: sys.h:980
StringBase str
Definition: str.h:2936
StreamBase()
Constructor.
Definition: iobase.h:149
bool isopen() const
Get whether stream is open.
Definition: iobase.h:906
This & operator<<(char ch)
Append a character.
Definition: iobase.h:539
FmtBasePrefix
Formatting integer base prefix type.
Definition: str.h:2331
int width
Field width to align in (default: 0)
Definition: str.h:2483
This & operator<<(const FmtFloatL &fmt)
Write formatted number field to stream.
Definition: iobase.h:1647
This & operator<<(ulong num)
Write formatted number to stream.
Definition: iobase.h:1508
const void * ptr
Pointer to format.
Definition: str.h:3265
This & operator<<(FmtPrecision prec)
Set floating point formatting precision.
Definition: iobase.h:696
IoWriter & bufwrite()
Advanced: Access primary write buffer.
Definition: iobase.h:846
This & operator<<(const FmtPtr &fmtptr)
Writer formatted pointer field to stream.
Definition: iobase.h:1669
virtual char * write_direct(Size size)
Get pointer for writing directly to buffer to append data.
Definition: iobase.h:290
This & operator<<(FmtWidth width)
Set field width to use.
Definition: iobase.h:458
This & operator<<(double num)
Write formatted floating-point number to stream.
Definition: iobase.h:1554
ulongl savepos_
Read/Write: Used to save buffered read position when switching between read/write.
Definition: iobase.h:1691
FmtSetInt num_int
Integer attributes.
Definition: str.h:2888
Reference and access existing string data.
Definition: substring.h:229
char ch
Character to format.
Definition: str.h:2915
FmtSetField fmt
Definition: str.h:2937
virtual bool write_direct_finish(Size size)
Finish writing directly to buffer.
Definition: iobase.h:341
bool writefmtnumf(TNum num, const FmtSetFloat &fmt, const FmtSetField *field=NULL)
Write formatted floating point number with field alignment.
Definition: iobase.h:1269
bool readline(String &str, ulong maxlen=0)
Read text line input from stream.
Definition: iobase.h:926
bool writefmtnum(TNum num, const FmtSetInt &fmt, const FmtSetField *field=NULL)
Write formatted signed number with field alignment.
Definition: iobase.h:1217
This & operator<<(const FmtUInt &fmt)
Write formatted number field to stream.
Definition: iobase.h:1627
Explicitly format a floating pointer number.
Definition: str.h:3148
char * write_direct_flush(Size &available, Size written_size, Size reserve_size)
Flush data written directly to buffer and get pointer for appending more.
Definition: iobase.h:325
Simple raw memory buffer.
Definition: rawbuffer.h:34
Holds field and alignment formatting attributes.
Definition: str.h:2481
This & operator<<(const FmtDump &fmtdump)
Write formatted data dump to stream.
Definition: iobase.h:755
Function not supported/implemented.
Definition: sys.h:1121
T num
Number to format.
Definition: str.h:3071
char * write_direct_multi(Size &available, Size reserve_size)
Get pointer for writing directly to buffer to append data and allow multiple passes for larger sizes...
Definition: iobase.h:307
FmtSetNull null
String to use for null values from strings (like String) or primitives (like Int) ...
Definition: str.h:2887
This & operator<<(long num)
Write formatted number to stream.
Definition: iobase.h:1478
Data not quotable (invalid text)
Definition: strscan.h:1905
Explicitly format a hex dump from buffer.
Definition: str.h:3294
FmtBase
Formatting integer base.
Definition: str.h:2318
#define EVO_PARAM_UNUSED(NAME)
Mark function parameter as unused to suppress "unreferenced parameter" compiler warnings on it...
Definition: sys.h:427
bool flush()
Flush any pending output in stream write buffer, if buffered.
Definition: iobase.h:937
FmtSetFloat num_flt
Floating point attributes.
Definition: str.h:2889
This & operator<<(This &)
No-op used by formatting helpers.
Definition: iobase.h:1334
IoReader bufrd_
Buffered reader.
Definition: iobase.h:1689
This & operator<<(double num)
Append a formatting floating point number.
Definition: iobase.h:716
Type
Quoting type.
Definition: strscan.h:1897
T::ExceptionInT ExceptionInT
Stream input exception type
Definition: iobase.h:799
Size writequoted(const char *buf, Size size, char delim, bool optional=false)
Write quoted text output to string.
Definition: iobase.h:970
ulong used
Buffer size in use in bytes.
Definition: rawbuffer.h:37
This & operator<<(long num)
Append a formatted signed integer.
Definition: iobase.h:642
This & operator<<(NewlineDefault nl)
Write default newline and flush stream.
Definition: iobase.h:485