1 |
786 |
skrzyp |
// This file is part of the uSTL library, an STL implementation.
|
2 |
|
|
//
|
3 |
|
|
// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net>
|
4 |
|
|
// This file is free software, distributed under the MIT License.
|
5 |
|
|
|
6 |
|
|
#ifndef SISTREAM_H_0CCA102229A49F5D65EE852E62B27CE2
|
7 |
|
|
#define SISTREAM_H_0CCA102229A49F5D65EE852E62B27CE2
|
8 |
|
|
|
9 |
|
|
#include "mistream.h"
|
10 |
|
|
#include "ustring.h"
|
11 |
|
|
#ifndef EOF
|
12 |
|
|
#define EOF (-1)
|
13 |
|
|
#endif
|
14 |
|
|
|
15 |
|
|
namespace ustl {
|
16 |
|
|
|
17 |
|
|
/// \class istringstream sistream.h ustl.h
|
18 |
|
|
/// \ingroup TextStreams
|
19 |
|
|
///
|
20 |
|
|
/// \brief A stream that reads textual data from a memory block.
|
21 |
|
|
///
|
22 |
|
|
class istringstream : public istream {
|
23 |
|
|
public:
|
24 |
|
|
static const size_type c_MaxDelimiters = 16; ///< Maximum number of word delimiters.
|
25 |
|
|
public:
|
26 |
|
|
istringstream (void);
|
27 |
|
|
istringstream (const void* p, size_type n);
|
28 |
|
|
explicit istringstream (const cmemlink& source);
|
29 |
|
|
void iread (int8_t& v) { v = skip_delimiters(); }
|
30 |
|
|
void iread (int32_t& v);
|
31 |
|
|
void iread (double& v);
|
32 |
|
|
void iread (bool& v);
|
33 |
|
|
void iread (wchar_t& v);
|
34 |
|
|
void iread (string& v);
|
35 |
|
|
#if HAVE_INT64_T
|
36 |
|
|
void iread (int64_t& v);
|
37 |
|
|
#endif
|
38 |
|
|
#if HAVE_LONG_LONG && (!HAVE_INT64_T || SIZE_OF_LONG_LONG > 8)
|
39 |
|
|
void iread (long long& v);
|
40 |
|
|
#endif
|
41 |
|
|
inline string str (void) const { string s; s.link (*this); return (s); }
|
42 |
|
|
inline istringstream& str (const string& s) { link (s); return (*this); }
|
43 |
|
|
inline istringstream& get (char& c) { return (read (&c, sizeof(c))); }
|
44 |
|
|
inline int get (void) { char c = EOF; get(c); return (c); }
|
45 |
|
|
istringstream& get (char* p, size_type n, char delim = '\n');
|
46 |
|
|
istringstream& get (string& s, char delim = '\n');
|
47 |
|
|
istringstream& getline (char* p, size_type n, char delim = '\n');
|
48 |
|
|
istringstream& getline (string& s, char delim = '\n');
|
49 |
|
|
istringstream& ignore (size_type n, char delim = '\0');
|
50 |
|
|
inline char peek (void) { int8_t v; iread (v); ungetc(); return (v); }
|
51 |
|
|
inline istringstream& putback (char) { ungetc(); return (*this); }
|
52 |
|
|
inline istringstream& unget (void) { ungetc(); return (*this); }
|
53 |
|
|
inline void set_delimiters (const char* delimiters);
|
54 |
|
|
inline void set_base (short base);
|
55 |
|
|
inline void set_decimal_separator (char) { }
|
56 |
|
|
inline void set_thousand_separator (char) { }
|
57 |
|
|
istringstream& read (void* buffer, size_type size);
|
58 |
|
|
inline istringstream& read (memlink& buf) { return (read (buf.begin(), buf.size())); }
|
59 |
|
|
inline istringstream& seekg (off_t p, seekdir d =beg) { istream::seekg(p,d); return (*this); }
|
60 |
|
|
inline int sync (void) { skip (remaining()); return (0); }
|
61 |
|
|
protected:
|
62 |
|
|
char skip_delimiters (void);
|
63 |
|
|
private:
|
64 |
|
|
inline void read_strz (string&) { assert (!"Reading nul characters is not allowed from text streams"); }
|
65 |
|
|
inline bool is_delimiter (char c) const;
|
66 |
|
|
template <typename T> void read_number (T& v);
|
67 |
|
|
private:
|
68 |
|
|
char m_Delimiters [c_MaxDelimiters];
|
69 |
|
|
uint8_t m_Base;
|
70 |
|
|
};
|
71 |
|
|
|
72 |
|
|
//----------------------------------------------------------------------
|
73 |
|
|
|
74 |
|
|
/// Sets the numeric base used to read numbers.
|
75 |
|
|
inline void istringstream::set_base (short base)
|
76 |
|
|
{
|
77 |
|
|
m_Base = base;
|
78 |
|
|
}
|
79 |
|
|
|
80 |
|
|
/// Sets delimiters to the contents of \p delimiters.
|
81 |
|
|
inline void istringstream::set_delimiters (const char* delimiters)
|
82 |
|
|
{
|
83 |
|
|
#if (__i386__ || __x86_64__) && CPU_HAS_SSE && HAVE_VECTOR_EXTENSIONS
|
84 |
|
|
typedef uint32_t v16ud_t __attribute__((vector_size(16)));
|
85 |
|
|
asm("xorps\t%%xmm0, %%xmm0\n\tmovups\t%%xmm0, %0":"=m"(*noalias_cast<v16ud_t*>(m_Delimiters))::"xmm0");
|
86 |
|
|
#else
|
87 |
|
|
memset (m_Delimiters, 0, sizeof(m_Delimiters));
|
88 |
|
|
#endif
|
89 |
|
|
memcpy (m_Delimiters, delimiters, min (strlen(delimiters),sizeof(m_Delimiters)-1));
|
90 |
|
|
}
|
91 |
|
|
|
92 |
|
|
/// Reads one type as another.
|
93 |
|
|
template <typename RealT, typename CastT>
|
94 |
|
|
inline void _cast_read (istringstream& is, RealT& v)
|
95 |
|
|
{
|
96 |
|
|
CastT cv;
|
97 |
|
|
is.iread (cv);
|
98 |
|
|
v = RealT (cv);
|
99 |
|
|
}
|
100 |
|
|
|
101 |
|
|
/// Reads a line of text from \p is into \p s
|
102 |
|
|
inline istringstream& getline (istringstream& is, string& s)
|
103 |
|
|
{ return (is.getline (s)); }
|
104 |
|
|
|
105 |
|
|
//----------------------------------------------------------------------
|
106 |
|
|
|
107 |
|
|
template <typename T> struct object_text_reader {
|
108 |
|
|
inline void operator()(istringstream& is, T& v) const { v.text_read (is); }
|
109 |
|
|
};
|
110 |
|
|
template <typename T> struct integral_text_object_reader {
|
111 |
|
|
inline void operator()(istringstream& is, T& v) const { is.iread (v); }
|
112 |
|
|
};
|
113 |
|
|
template <typename T>
|
114 |
|
|
inline istringstream& operator>> (istringstream& is, T& v) {
|
115 |
|
|
typedef typename tm::Select <numeric_limits<T>::is_integral,
|
116 |
|
|
integral_text_object_reader<T>, object_text_reader<T> >::Result object_reader_t;
|
117 |
|
|
object_reader_t()(is, v);
|
118 |
|
|
return (is);
|
119 |
|
|
}
|
120 |
|
|
|
121 |
|
|
//----------------------------------------------------------------------
|
122 |
|
|
|
123 |
|
|
template <> struct object_text_reader<string> {
|
124 |
|
|
inline void operator()(istringstream& is, string& v) const { is.iread (v); }
|
125 |
|
|
};
|
126 |
|
|
#define ISTRSTREAM_CAST_OPERATOR(RealT, CastT) \
|
127 |
|
|
template <> struct integral_text_object_reader<RealT> { \
|
128 |
|
|
inline void operator() (istringstream& is, RealT& v) const \
|
129 |
|
|
{ _cast_read<RealT,CastT>(is, v); } \
|
130 |
|
|
};
|
131 |
|
|
ISTRSTREAM_CAST_OPERATOR (uint8_t, int8_t)
|
132 |
|
|
ISTRSTREAM_CAST_OPERATOR (int16_t, int32_t)
|
133 |
|
|
ISTRSTREAM_CAST_OPERATOR (uint16_t, int32_t)
|
134 |
|
|
ISTRSTREAM_CAST_OPERATOR (uint32_t, int32_t)
|
135 |
|
|
ISTRSTREAM_CAST_OPERATOR (float, double)
|
136 |
|
|
#if HAVE_THREE_CHAR_TYPES
|
137 |
|
|
ISTRSTREAM_CAST_OPERATOR (char, int8_t)
|
138 |
|
|
#endif
|
139 |
|
|
#if HAVE_INT64_T
|
140 |
|
|
ISTRSTREAM_CAST_OPERATOR (uint64_t, int64_t)
|
141 |
|
|
#endif
|
142 |
|
|
#if SIZE_OF_LONG == SIZE_OF_INT
|
143 |
|
|
ISTRSTREAM_CAST_OPERATOR (long, int)
|
144 |
|
|
ISTRSTREAM_CAST_OPERATOR (unsigned long,int)
|
145 |
|
|
#endif
|
146 |
|
|
#if HAVE_LONG_LONG && (!HAVE_INT64_T || SIZE_OF_LONG_LONG > 8)
|
147 |
|
|
ISTRSTREAM_CAST_OPERATOR (unsigned long long, long long)
|
148 |
|
|
#endif
|
149 |
|
|
#undef ISTRSTREAM_CAST_OPERATOR
|
150 |
|
|
|
151 |
|
|
} // namespace ustl
|
152 |
|
|
|
153 |
|
|
#endif
|