libshevek
iostring.hh
1 /* iostring.hh - Read and write strings in parts.
2  * Copyright 2007-2008 Bas Wijnen <wijnen@debian.org>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef SHEVEK_IOSTRING_HH
19 #define SHEVEK_IOSTRING_HH
20 
21 #include <string>
22 #include <stack>
23 #include <sstream>
24 #include <glibmm.h>
25 
26 namespace shevek
27 {
29 
32  class istring
33  {
34  // The data to parse.
35  Glib::ustring data;
36  // Pointer to data still to be parsed.
37  std::stack <Glib::ustring::size_type> pos;
38 
39  // Read a variable.
40  template <typename T>
41  bool read_var (Glib::ustring const &format, T &ret, Glib::ustring::size_type &inpos);
42 
43  // Read away whitespace.
44  void del_whitespace ();
45 
46  // Check for a constant.
47  bool read_const (Glib::ustring const &format, Glib::ustring::size_type &inpos);
48  public:
49  // Constructors: fill data and make one stack level.
51  istring () { pos.push (0); }
53  istring (Glib::ustring const &str) { init (str); }
55  void init (Glib::ustring const &str)
56  { data = str; while (!pos.empty ()) pos.pop (); pos.push (0); }
57 
58  // Stack functions.
60  void push () { pos.push (pos.top ()); }
62 
65  int pop (bool keep = false);
67  void reset () { pos.top () = 0; }
68 
70  Glib::ustring rest () const { return data.substr (pos.top ()); }
71 
73  void skip (Glib::ustring::size_type p) { pos.top () += p; }
74 
76  bool operator() (Glib::ustring const &format)
77  {
78  push ();
79  Glib::ustring::size_type inpos = 0;
80  bool ret = read_const (format, inpos)
81  && inpos == format.size ();
82  pop (ret);
83  return ret;
84  }
85 
87  template <typename T1>
88  bool operator() (Glib::ustring const &format, T1 &arg1)
89  {
90  push ();
91  Glib::ustring::size_type inpos = 0;
92  bool ret = read_const (format, inpos)
93  && read_var (format, arg1, inpos)
94  && read_const (format, inpos)
95  && inpos == format.size ();
96  pop (ret);
97  return ret;
98  }
99 
101  template <typename T1, typename T2>
102  bool operator() (Glib::ustring const &format, T1 &arg1,
103  T2 &arg2)
104  {
105  push ();
106  Glib::ustring::size_type inpos = 0;
107  bool ret = read_const (format, inpos)
108  && read_var (format, arg1, inpos)
109  && read_const (format, inpos)
110  && read_var (format, arg2, inpos)
111  && read_const (format, inpos)
112  && inpos == format.size ();
113  pop (ret);
114  return ret;
115  }
116 
118  template <typename T1, typename T2, typename T3>
119  bool operator() (Glib::ustring const &format, T1 &arg1,
120  T2 &arg2, T3 &arg3)
121  {
122  push ();
123  Glib::ustring::size_type inpos = 0;
124  bool ret = read_const (format, inpos)
125  && read_var (format, arg1, inpos)
126  && read_const (format, inpos)
127  && read_var (format, arg2, inpos)
128  && read_const (format, inpos)
129  && read_var (format, arg3, inpos)
130  && read_const (format, inpos)
131  && inpos == format.size ();
132  pop (ret);
133  return ret;
134  }
135 
137  template <typename T1, typename T2, typename T3, typename T4>
138  bool operator() (Glib::ustring const &format, T1 &arg1,
139  T2 &arg2, T3 &arg3, T4 &arg4)
140  {
141  push ();
142  Glib::ustring::size_type inpos = 0;
143  bool ret = read_const (format, inpos)
144  && read_var (format, arg1, inpos)
145  && read_const (format, inpos)
146  && read_var (format, arg2, inpos)
147  && read_const (format, inpos)
148  && read_var (format, arg3, inpos)
149  && read_const (format, inpos)
150  && read_var (format, arg4, inpos)
151  && read_const (format, inpos)
152  && inpos == format.size ();
153  pop (ret);
154  return ret;
155  }
156 
158  template <typename T1, typename T2, typename T3, typename T4,
159  typename T5>
160  bool operator() (Glib::ustring const &format, T1 &arg1,
161  T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5)
162  {
163  push ();
164  Glib::ustring::size_type inpos = 0;
165  bool ret = read_const (format, inpos)
166  && read_var (format, arg1, inpos)
167  && read_const (format, inpos)
168  && read_var (format, arg2, inpos)
169  && read_const (format, inpos)
170  && read_var (format, arg3, inpos)
171  && read_const (format, inpos)
172  && read_var (format, arg4, inpos)
173  && read_const (format, inpos)
174  && read_var (format, arg5, inpos)
175  && read_const (format, inpos)
176  && inpos == format.size ();
177  pop (ret);
178  return ret;
179  }
180 
182  template <typename T1, typename T2, typename T3, typename T4,
183  typename T5, typename T6>
184  bool operator() (Glib::ustring const &format, T1 &arg1,
185  T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5,
186  T6 &arg6)
187  {
188  push ();
189  Glib::ustring::size_type inpos = 0;
190  bool ret = read_const (format, inpos)
191  && read_var (format, arg1, inpos)
192  && read_const (format, inpos)
193  && read_var (format, arg2, inpos)
194  && read_const (format, inpos)
195  && read_var (format, arg3, inpos)
196  && read_const (format, inpos)
197  && read_var (format, arg4, inpos)
198  && read_const (format, inpos)
199  && read_var (format, arg5, inpos)
200  && read_const (format, inpos)
201  && read_var (format, arg6, inpos)
202  && read_const (format, inpos)
203  && inpos == format.size ();
204  pop (ret);
205  return ret;
206  }
207 
209  template <typename T1, typename T2, typename T3, typename T4,
210  typename T5, typename T6, typename T7>
211  bool operator() (Glib::ustring const &format, T1 &arg1,
212  T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5,
213  T6 &arg6, T7 &arg7)
214  {
215  push ();
216  Glib::ustring::size_type inpos = 0;
217  bool ret = read_const (format, inpos)
218  && read_var (format, arg1, inpos)
219  && read_const (format, inpos)
220  && read_var (format, arg2, inpos)
221  && read_const (format, inpos)
222  && read_var (format, arg3, inpos)
223  && read_const (format, inpos)
224  && read_var (format, arg4, inpos)
225  && read_const (format, inpos)
226  && read_var (format, arg5, inpos)
227  && read_const (format, inpos)
228  && read_var (format, arg6, inpos)
229  && read_const (format, inpos)
230  && read_var (format, arg7, inpos)
231  && read_const (format, inpos)
232  && inpos == format.size ();
233  pop (ret);
234  return ret;
235  }
236 
238  template <typename T1, typename T2, typename T3, typename T4,
239  typename T5, typename T6, typename T7, typename T8>
240  bool operator() (Glib::ustring const &format, T1 &arg1,
241  T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5,
242  T6 &arg6, T7 &arg7, T8 &arg8)
243  {
244  push ();
245  Glib::ustring::size_type inpos = 0;
246  bool ret = read_const (format, inpos)
247  && read_var (format, arg1, inpos)
248  && read_const (format, inpos)
249  && read_var (format, arg2, inpos)
250  && read_const (format, inpos)
251  && read_var (format, arg3, inpos)
252  && read_const (format, inpos)
253  && read_var (format, arg4, inpos)
254  && read_const (format, inpos)
255  && read_var (format, arg5, inpos)
256  && read_const (format, inpos)
257  && read_var (format, arg6, inpos)
258  && read_const (format, inpos)
259  && read_var (format, arg7, inpos)
260  && read_const (format, inpos)
261  && read_var (format, arg8, inpos)
262  && read_const (format, inpos)
263  && inpos == format.size ();
264  pop (ret);
265  return ret;
266  }
267 
269 
272  template <typename T>
273  static T direct (Glib::ustring const &data,
274  Glib::ustring const &format,
275  T def = T ())
276  {
277  T ret;
278  istring tmp (data);
279  if (!tmp (format, ret))
280  ret = def;
281  return ret;
282  }
283  };
284 
286 
289  template <typename T>
290  bool istring::read_var (Glib::ustring const &format, T &ret,
291  Glib::ustring::size_type &inpos)
292  {
293  ++inpos;
294  std::istringstream s (data.substr (pos.top ()));
295  s >> ret;
296  std::streampos p = s.tellg ();
297  if (!s || p < 0)
298  return false;
299  pos.top () += p;
300  return true;
301  }
302 
304  template <> bool istring::read_var <double> (Glib::ustring const &format, double &ret, Glib::ustring::size_type &inpos);
305 
307  template <> bool istring::read_var <float> (Glib::ustring const &format, float &ret, Glib::ustring::size_type &inpos);
308 
310  template <> bool istring::read_var <Glib::ustring> (Glib::ustring const &format, Glib::ustring &ret, Glib::ustring::size_type &inpos);
311 
313  template <> bool istring::read_var <int> (Glib::ustring const &format, int &ret, Glib::ustring::size_type &inpos);
314 
316  template <> bool istring::read_var <unsigned> (Glib::ustring const &format, unsigned &ret, Glib::ustring::size_type &inpos);
317 
319 
322  class ostring
323  {
324  Glib::ustring data;
325  Glib::ustring format;
326  Glib::ustring::size_type pos;
327  void write_const ();
328  template <typename T> void write_var (T const &a,
329  Glib::ustring const &flags,
330  unsigned width, unsigned precision);
331  template <typename T> void write_var_raw (T const &a);
332  ostring &init (Glib::ustring const &f);
333  // If you get a linker error to this line, you have tried to insert a std::string into a shevek::ostring.
334  // Fix the program by turning it into a Glib::ustring first, or by using a shevek::rostring instead.
335  template <typename T> ostring &operator ()(T const &a) { write_const (); write_var_raw (a); return *this; }
336  ostring &operator ()();
337  public:
339  operator Glib::ustring () const { return data; }
341  Glib::ustring operator+ (Glib::ustring const &that) const { return data + that; }
343  friend std::ostream &operator<< (std::ostream &s, ostring const &o) { return s << o.data; }
345  ostring (Glib::ustring const &fmt) { init (fmt)(); }
347  template <typename T1>
348  ostring (Glib::ustring const &fmt, T1 const &a1)
349  { init (fmt)(a1)(); }
351  template <typename T1, typename T2>
352  ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2)
353  { init (fmt)(a1)(a2)(); }
355  template <typename T1, typename T2, typename T3>
356  ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2,
357  T3 const &a3)
358  { init (fmt)(a1)(a2)(a3)(); }
360  template <typename T1, typename T2, typename T3, typename T4>
361  ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2,
362  T3 const &a3, T4 const &a4)
363  { init (fmt)(a1)(a2)(a3)(a4)(); }
365  template <typename T1, typename T2, typename T3, typename T4,
366  typename T5>
367  ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2,
368  T3 const &a3, T4 const &a4, T5 const &a5)
369  { init (fmt)(a1)(a2)(a3)(a4)(a5)(); }
371  template <typename T1, typename T2, typename T3, typename T4,
372  typename T5, typename T6>
373  ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2,
374  T3 const &a3, T4 const &a4, T5 const &a5,
375  T6 const &a6)
376  { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(); }
378  template <typename T1, typename T2, typename T3, typename T4,
379  typename T5, typename T6, typename T7>
380  ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2,
381  T3 const &a3, T4 const &a4, T5 const &a5,
382  T6 const &a6, T7 const &a7)
383  { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(); }
385  template <typename T1, typename T2, typename T3, typename T4,
386  typename T5, typename T6, typename T7 ,typename T8>
387  ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2,
388  T3 const &a3, T4 const &a4, T5 const &a5,
389  T6 const &a6, T7 const &a7, T8 const &a8)
390  { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(); }
392  template <typename T1, typename T2, typename T3, typename T4,
393  typename T5, typename T6, typename T7 ,typename T8,
394  typename T9>
395  ostring (Glib::ustring const &fmt, T1 const &a1, T2 const &a2,
396  T3 const &a3, T4 const &a4, T5 const &a5,
397  T6 const &a6, T7 const &a7, T8 const &a8,
398  T9 const &a9)
399  { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(); }
400  };
401 
403 
405  template <typename T> void ostring::write_var_raw (T const &a)
406  {
407  unsigned width = 0, precision = 0;
408  Glib::ustring flags;
409  while (pos < format.size ()
410  && (format[pos] < 'a' || format[pos] > 'z')
411  && (format[pos] < 'A' || format[pos] > 'Z')
412  && (format[pos] < '1' || format[pos] > '9'))
413  flags += format[pos++];
414  while (pos < format.size () && format[pos] >= '0'
415  && format[pos] <= '9')
416  {
417  width *= 10;
418  width += format[pos++] - '0';
419  }
420  if (pos < format.size () && format[pos] == '.')
421  {
422  ++pos;
423  while (pos < format.size () && format[pos] >= '0'
424  && format[pos] <= '9')
425  {
426  precision *= 10;
427  precision += format[pos++] - '0';
428  }
429  }
430  return write_var (a, flags, width, precision);
431  }
432 
434 
436  template <typename T> void ostring::write_var (T const &a,
437  Glib::ustring const &flags,
438  unsigned width, unsigned precision)
439  {
440  (void)flags;
441  (void)width;
442  (void)precision;
443  if (pos < format.size ())
444  ++pos;
445  std::ostringstream s;
446  s << a;
447  data += s.str ();
448  }
449 
451  template <> void ostring::write_var <unsigned short> (unsigned short const &a, Glib::ustring const &flags, unsigned width, unsigned precision);
453  template <> void ostring::write_var <short> (short const &a, Glib::ustring const &flags, unsigned width, unsigned precision);
455  template <> void ostring::write_var <unsigned> (unsigned const &a, Glib::ustring const &flags, unsigned width, unsigned precision);
457  template <> void ostring::write_var <int> (int const &a, Glib::ustring const &flags, unsigned width, unsigned precision);
459  template <> void ostring::write_var <Glib::ustring> (Glib::ustring const &a, Glib::ustring const &flags, unsigned width, unsigned precision);
460 
462 
465  template <> void ostring::write_var_raw <std::string> (std::string const &a);
466  template <> bool istring::read_var <std::string> (Glib::ustring const &format, std::string &ret, Glib::ustring::size_type &inpos);
467 
469  class ristring
470  {
471  // The data to parse.
472  std::string data;
473  // Pointer to data still to be parsed.
474  std::stack <std::string::size_type> pos;
475 
476  // Read a variable.
477  template <typename T>
478  bool read_var (std::string const &format, T &ret, std::string::size_type &inpos);
479 
480  // Read away whitespace.
481  void del_whitespace ();
482 
483  // Check for a constant.
484  bool read_const (std::string const &format, std::string::size_type &inpos);
485  public:
486  // Constructors: fill data and make one stack level.
488  ristring () { pos.push (0); }
490  ristring (std::string const &str) { init (str); }
492  void init (std::string const &str) { data = str; while (!pos.empty ()) pos.pop (); pos.push (0); }
493 
494  // Stack functions.
496  void push () { pos.push (pos.top ()); }
498 
501  int pop (bool keep = false);
503  void reset () { pos.top () = 0; }
504 
506  std::string rest () const { return data.substr (pos.top ()); }
507 
509  void skip (std::string::size_type p) { pos.top () += p; }
510 
512  bool operator() (std::string const &format)
513  {
514  push ();
515  std::string::size_type inpos = 0;
516  bool ret = read_const (format, inpos)
517  && inpos == format.size ();
518  pop (ret);
519  return ret;
520  }
521 
523  template <typename T1>
524  bool operator() (std::string const &format, T1 &arg1)
525  {
526  push ();
527  std::string::size_type inpos = 0;
528  bool ret = read_const (format, inpos)
529  && read_var (format, arg1, inpos)
530  && read_const (format, inpos)
531  && inpos == format.size ();
532  pop (ret);
533  return ret;
534  }
535 
537  template <typename T1, typename T2>
538  bool operator() (std::string const &format, T1 &arg1,
539  T2 &arg2)
540  {
541  push ();
542  std::string::size_type inpos = 0;
543  bool ret = read_const (format, inpos)
544  && read_var (format, arg1, inpos)
545  && read_const (format, inpos)
546  && read_var (format, arg2, inpos)
547  && read_const (format, inpos)
548  && inpos == format.size ();
549  pop (ret);
550  return ret;
551  }
552 
554  template <typename T1, typename T2, typename T3>
555  bool operator() (std::string const &format, T1 &arg1,
556  T2 &arg2, T3 &arg3)
557  {
558  push ();
559  std::string::size_type inpos = 0;
560  bool ret = read_const (format, inpos)
561  && read_var (format, arg1, inpos)
562  && read_const (format, inpos)
563  && read_var (format, arg2, inpos)
564  && read_const (format, inpos)
565  && read_var (format, arg3, inpos)
566  && read_const (format, inpos)
567  && inpos == format.size ();
568  pop (ret);
569  return ret;
570  }
571 
573  template <typename T1, typename T2, typename T3, typename T4>
574  bool operator() (std::string const &format, T1 &arg1,
575  T2 &arg2, T3 &arg3, T4 &arg4)
576  {
577  push ();
578  std::string::size_type inpos = 0;
579  bool ret = read_const (format, inpos)
580  && read_var (format, arg1, inpos)
581  && read_const (format, inpos)
582  && read_var (format, arg2, inpos)
583  && read_const (format, inpos)
584  && read_var (format, arg3, inpos)
585  && read_const (format, inpos)
586  && read_var (format, arg4, inpos)
587  && read_const (format, inpos)
588  && inpos == format.size ();
589  pop (ret);
590  return ret;
591  }
592 
594  template <typename T1, typename T2, typename T3, typename T4,
595  typename T5>
596  bool operator() (std::string const &format, T1 &arg1,
597  T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5)
598  {
599  push ();
600  std::string::size_type inpos = 0;
601  bool ret = read_const (format, inpos)
602  && read_var (format, arg1, inpos)
603  && read_const (format, inpos)
604  && read_var (format, arg2, inpos)
605  && read_const (format, inpos)
606  && read_var (format, arg3, inpos)
607  && read_const (format, inpos)
608  && read_var (format, arg4, inpos)
609  && read_const (format, inpos)
610  && read_var (format, arg5, inpos)
611  && read_const (format, inpos)
612  && inpos == format.size ();
613  pop (ret);
614  return ret;
615  }
616 
618  template <typename T1, typename T2, typename T3, typename T4,
619  typename T5, typename T6>
620  bool operator() (std::string const &format, T1 &arg1,
621  T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5,
622  T6 &arg6)
623  {
624  push ();
625  std::string::size_type inpos = 0;
626  bool ret = read_const (format, inpos)
627  && read_var (format, arg1, inpos)
628  && read_const (format, inpos)
629  && read_var (format, arg2, inpos)
630  && read_const (format, inpos)
631  && read_var (format, arg3, inpos)
632  && read_const (format, inpos)
633  && read_var (format, arg4, inpos)
634  && read_const (format, inpos)
635  && read_var (format, arg5, inpos)
636  && read_const (format, inpos)
637  && read_var (format, arg6, inpos)
638  && read_const (format, inpos)
639  && inpos == format.size ();
640  pop (ret);
641  return ret;
642  }
643 
645  template <typename T1, typename T2, typename T3, typename T4,
646  typename T5, typename T6, typename T7>
647  bool operator() (std::string const &format, T1 &arg1,
648  T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5,
649  T6 &arg6, T7 &arg7)
650  {
651  push ();
652  std::string::size_type inpos = 0;
653  bool ret = read_const (format, inpos)
654  && read_var (format, arg1, inpos)
655  && read_const (format, inpos)
656  && read_var (format, arg2, inpos)
657  && read_const (format, inpos)
658  && read_var (format, arg3, inpos)
659  && read_const (format, inpos)
660  && read_var (format, arg4, inpos)
661  && read_const (format, inpos)
662  && read_var (format, arg5, inpos)
663  && read_const (format, inpos)
664  && read_var (format, arg6, inpos)
665  && read_const (format, inpos)
666  && read_var (format, arg7, inpos)
667  && read_const (format, inpos)
668  && inpos == format.size ();
669  pop (ret);
670  return ret;
671  }
672 
674  template <typename T1, typename T2, typename T3, typename T4,
675  typename T5, typename T6, typename T7, typename T8>
676  bool operator() (std::string const &format, T1 &arg1,
677  T2 &arg2, T3 &arg3, T4 &arg4, T5 &arg5,
678  T6 &arg6, T7 &arg7, T8 &arg8)
679  {
680  push ();
681  std::string::size_type inpos = 0;
682  bool ret = read_const (format, inpos)
683  && read_var (format, arg1, inpos)
684  && read_const (format, inpos)
685  && read_var (format, arg2, inpos)
686  && read_const (format, inpos)
687  && read_var (format, arg3, inpos)
688  && read_const (format, inpos)
689  && read_var (format, arg4, inpos)
690  && read_const (format, inpos)
691  && read_var (format, arg5, inpos)
692  && read_const (format, inpos)
693  && read_var (format, arg6, inpos)
694  && read_const (format, inpos)
695  && read_var (format, arg7, inpos)
696  && read_const (format, inpos)
697  && read_var (format, arg8, inpos)
698  && read_const (format, inpos)
699  && inpos == format.size ();
700  pop (ret);
701  return ret;
702  }
703 
705 
708  template <typename T>
709  static T direct (std::string const &data,
710  std::string const &format,
711  T def = T ())
712  {
713  T ret;
714  istring tmp (data);
715  if (!tmp (format, ret))
716  ret = def;
717  return ret;
718  }
719  };
720 
722 
725  template <typename T>
726  bool ristring::read_var (std::string const &format, T &ret, std::string::size_type &inpos)
727  {
728  (void *)&format;
729  ++inpos;
730  std::istringstream s (data.substr (pos.top ()));
731  s >> ret;
732  std::streampos p = s.tellg ();
733  if (!s || p < 0)
734  return false;
735  pos.top () += p;
736  return true;
737  }
738 
740  template <>
741  bool ristring::read_var <double> (std::string const &format,
742  double &ret, std::string::size_type &inpos);
743 
745  template <>
746  bool ristring::read_var <float> (std::string const &format,
747  float &ret, std::string::size_type &inpos);
748 
750  template <>
751  bool ristring::read_var <std::string> (std::string const &format,
752  std::string &ret, std::string::size_type &inpos);
753 
755  template <>
756  bool ristring::read_var <int> (std::string const &format,
757  int &ret, std::string::size_type &inpos);
758 
760  template <>
761  bool ristring::read_var <unsigned> (std::string const &format,
762  unsigned &ret, std::string::size_type &inpos);
763 
765  class rostring
766  {
767  std::string data;
768  std::string format;
769  std::string::size_type pos;
770  void write_const ();
771  template <typename T> void write_var (T const &a,
772  std::string const &flags,
773  unsigned width, unsigned precision);
774  template <typename T> void write_var_raw (T const &a);
775  rostring &init (std::string const &f);
776  template <typename T> rostring &operator ()(T const &a)
777  { write_const (); write_var_raw (a); return *this; }
779  public:
781  operator std::string () const { return data; }
783  std::string operator+ (std::string const &that) const { return data + that; }
785  friend std::ostream &operator<< (std::ostream &s, rostring const &o) { return s << o.data; }
787  rostring (std::string const &fmt)
788  { init (fmt)(); }
790  template <typename T1>
791  rostring (std::string const &fmt, T1 const &a1)
792  { init (fmt)(a1)(); }
794  template <typename T1, typename T2>
795  rostring (std::string const &fmt, T1 const &a1, T2 const &a2)
796  { init (fmt)(a1)(a2)(); }
798  template <typename T1, typename T2, typename T3>
799  rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3)
800  { init (fmt)(a1)(a2)(a3)(); }
802  template <typename T1, typename T2, typename T3, typename T4>
803  rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4)
804  { init (fmt)(a1)(a2)(a3)(a4)(); }
806  template <typename T1, typename T2, typename T3, typename T4, typename T5>
807  rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5)
808  { init (fmt)(a1)(a2)(a3)(a4)(a5)(); }
810  template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
811  rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6)
812  { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(); }
814  template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
815  rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7)
816  { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(); }
818  template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 ,typename T8>
819  rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7, T8 const &a8)
820  { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(); }
822  template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 ,typename T8, typename T9>
823  rostring (std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7, T8 const &a8, T9 const &a9)
824  { init (fmt)(a1)(a2)(a3)(a4)(a5)(a6)(a7)(a8)(a9)(); }
825  };
826 
828 
830  template <typename T> void rostring::write_var_raw (T const &a)
831  {
832  unsigned width = 0, precision = 0;
833  std::string flags;
834  while (pos < format.size ()
835  && (format[pos] < 'a' || format[pos] > 'z')
836  && (format[pos] < 'A' || format[pos] > 'Z')
837  && (format[pos] < '1' || format[pos] > '9'))
838  flags += format[pos++];
839  while (pos < format.size () && format[pos] >= '0'
840  && format[pos] <= '9')
841  {
842  width *= 10;
843  width += format[pos++] - '0';
844  }
845  if (pos < format.size () && format[pos] == '.')
846  {
847  ++pos;
848  while (pos < format.size () && format[pos] >= '0'
849  && format[pos] <= '9')
850  {
851  precision *= 10;
852  precision += format[pos++] - '0';
853  }
854  }
855  return write_var (a, flags, width, precision);
856  }
857 
859 
861  template <typename T> void rostring::write_var (T const &a, std::string const &flags, unsigned width, unsigned precision)
862  {
863  (void)flags;
864  (void)width;
865  (void)precision;
866  if (pos < format.size ())
867  ++pos;
868  std::ostringstream s;
869  s << a;
870  data += s.str ();
871  }
872 
874 
876  template <> void rostring::write_var <unsigned> (unsigned const &a, std::string const &flags, unsigned width, unsigned precision);
878 
880  template <> void rostring::write_var <int> (int const &a, std::string const &flags, unsigned width, unsigned precision);
881 
883 
886  template <> void rostring::write_var_raw <Glib::ustring> (Glib::ustring const &a);
887  template <> bool ristring::read_var <Glib::ustring> (std::string const &format, Glib::ustring &ret, std::string::size_type &inpos);
888 }
889 
890 #endif
shevek::ostring is a C++ version of printf.
Definition: iostring.hh:322
void push()
Push the current position to the stack so it can be restored later.
Definition: iostring.hh:496
Glib::ustring rest() const
Get remaining string.
Definition: iostring.hh:70
ostring(Glib::ustring const &fmt)
Create a string with a constant format.
Definition: iostring.hh:345
ostring(Glib::ustring const &fmt, T1 const &a1, T2 const &a2)
Create a string with two arguments.
Definition: iostring.hh:352
void init(std::string const &str)
Set new data to an existing istring.
Definition: iostring.hh:492
ostring(Glib::ustring const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4)
Create a string with four arguments.
Definition: iostring.hh:361
rostring(std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4)
Create a string with four arguments.
Definition: iostring.hh:803
shevek::rostring is identical to shevek::ostring, but it uses std::string instead of Glib::ustring...
Definition: iostring.hh:765
ostring(Glib::ustring const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7)
Create a string with seven arguments.
Definition: iostring.hh:380
rostring(std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3)
Create a string with three arguments.
Definition: iostring.hh:799
static T direct(std::string const &data, std::string const &format, T def=T())
Read a variable from given data and return it.
Definition: iostring.hh:709
ostring(Glib::ustring const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7, T8 const &a8, T9 const &a9)
Create a string with nine arguments.
Definition: iostring.hh:395
std::string rest() const
Get remaining string.
Definition: iostring.hh:506
Definition: args.hh:52
istring(Glib::ustring const &str)
Create a new istring with data.
Definition: iostring.hh:53
rostring(std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7)
Create a string with seven arguments.
Definition: iostring.hh:815
void reset()
Set the current position to 0, but don&#39;t change the stack.
Definition: iostring.hh:67
rostring(std::string const &fmt, T1 const &a1)
Create a string with one argument.
Definition: iostring.hh:791
rostring(std::string const &fmt, T1 const &a1, T2 const &a2)
Create a string with two arguments.
Definition: iostring.hh:795
ristring()
Create a new istring with no data.
Definition: iostring.hh:488
void skip(std::string::size_type p)
Skip some characters.
Definition: iostring.hh:509
rostring(std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7, T8 const &a8, T9 const &a9)
Create a string with nine arguments.
Definition: iostring.hh:823
void push()
Push the current position to the stack so it can be restored later.
Definition: iostring.hh:60
rostring(std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5)
Create a string with five arguments.
Definition: iostring.hh:807
ostring(Glib::ustring const &fmt, T1 const &a1)
Create a string with one argument.
Definition: iostring.hh:348
ostring(Glib::ustring const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7, T8 const &a8)
Create a string with eight arguments.
Definition: iostring.hh:387
void reset()
Set the current position to 0, but don&#39;t change the stack.
Definition: iostring.hh:503
shevek::istring is a C++ version of scanf.
Definition: iostring.hh:32
ostring(Glib::ustring const &fmt, T1 const &a1, T2 const &a2, T3 const &a3)
Create a string with three arguments.
Definition: iostring.hh:356
istring()
Create a new istring with no data.
Definition: iostring.hh:51
rostring(std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6, T7 const &a7, T8 const &a8)
Create a string with eight arguments.
Definition: iostring.hh:819
static T direct(Glib::ustring const &data, Glib::ustring const &format, T def=T())
Read a variable from given data and return it.
Definition: iostring.hh:273
shevek::ristring is identical to shevek::istring, but it uses std::string instead of Glib::ustring...
Definition: iostring.hh:469
ristring(std::string const &str)
Create a new istring with data.
Definition: iostring.hh:490
rostring(std::string const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6)
Create a string with six arguments.
Definition: iostring.hh:811
ostring(Glib::ustring const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5)
Create a string with five arguments.
Definition: iostring.hh:367
ostring(Glib::ustring const &fmt, T1 const &a1, T2 const &a2, T3 const &a3, T4 const &a4, T5 const &a5, T6 const &a6)
Create a string with six arguments.
Definition: iostring.hh:373
void init(Glib::ustring const &str)
Set new data to an existing istring.
Definition: iostring.hh:55
int pop(bool keep=false)
Pop the last pushed position from the stack.
bool operator()(Glib::ustring const &format)
Read a constant string from the input.
Definition: iostring.hh:76
void skip(Glib::ustring::size_type p)
Skip some characters.
Definition: iostring.hh:73
rostring(std::string const &fmt)
Create a string with a constant format.
Definition: iostring.hh:787