1 // This file is part of the ustl library, an STL implementation.
3 // Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
4 // This file is free software, distributed under the MIT License.
15 const char ios_base::c_DefaultDelimiters
[istringstream::c_MaxDelimiters
] = " \t\n\r;:,.?";
17 /// Default constructor.
18 istringstream::istringstream (void)
22 set_delimiters (c_DefaultDelimiters
);
25 istringstream::istringstream (const void* p
, size_type n
)
30 set_delimiters (c_DefaultDelimiters
);
33 istringstream::istringstream (const cmemlink
& source
)
38 set_delimiters (c_DefaultDelimiters
);
41 /// Sets delimiters to the contents of \p delimiters.
42 void istringstream::set_delimiters (const char* delimiters
)
44 fill (VectorRange (m_Delimiters
), '\0');
45 strncpy (m_Delimiters
, delimiters
, VectorSize(m_Delimiters
)-1);
48 inline bool istringstream::is_delimiter (char c
) const
50 return (memchr (m_Delimiters
, c
, VectorSize(m_Delimiters
)-1));
53 char istringstream::skip_delimiters (void)
55 char c
= m_Delimiters
[0];
56 while (is_delimiter(c
) && (remaining() || underflow()))
61 void istringstream::iread (int8_t& v
)
63 v
= skip_delimiters();
66 typedef istringstream::iterator issiter_t
;
68 inline void str_to_num (issiter_t i
, issiter_t
* iend
, uint8_t base
, T
& v
)
69 { v
= strtol (i
, const_cast<char**>(iend
), base
); }
70 template <> inline void str_to_num (issiter_t i
, issiter_t
* iend
, uint8_t, double& v
)
71 { v
= strtod (i
, const_cast<char**>(iend
)); }
73 template <> inline void str_to_num (issiter_t i
, issiter_t
* iend
, uint8_t base
, long long& v
)
74 { v
= strtoll (i
, const_cast<char**>(iend
), base
); }
78 inline void istringstream::read_number (T
& v
)
81 if (skip_delimiters() == m_Delimiters
[0])
86 str_to_num
<T
> (ipos(), &ilast
, m_Base
, v
);
87 } while (ilast
== end() && underflow());
88 skip (distance (ipos(), ilast
));
91 void istringstream::iread (int32_t& v
) { read_number (v
); }
92 void istringstream::iread (double& v
) { read_number (v
); }
94 void istringstream::iread (int64_t& v
) { read_number (v
); }
96 #if HAVE_LONG_LONG && (!HAVE_INT64_T || SIZE_OF_LONG_LONG > 8)
97 void istringstream::iread (long long& v
) { read_number (v
); }
100 void istringstream::iread (wchar_t& v
)
102 if ((v
= skip_delimiters()) == wchar_t(m_Delimiters
[0]))
104 size_t cs
= Utf8SequenceBytes (v
) - 1;
105 if (remaining() >= cs
|| underflow(cs
) >= cs
) {
107 v
= *utf8in (ipos());
112 void istringstream::iread (bool& v
)
114 static const char tf
[2][8] = { "false", "true" };
115 char c
= skip_delimiters();
116 v
= (c
== 't' || c
== '1');
119 for (const char* tv
= tf
[v
]; c
== *tv
&& (remaining() || underflow()); ++tv
)
124 void istringstream::iread (string
& v
)
127 char prevc
, quoteChar
= 0, c
= skip_delimiters();
128 if (c
== '\"' || c
== '\'')
132 while (remaining() || underflow()) {
135 if (!quoteChar
&& is_delimiter(c
))
139 case 't': c
= '\t'; break;
140 case 'n': c
= '\n'; break;
141 case 'r': c
= '\r'; break;
142 case 'b': c
= '\b'; break;
143 case 'E': c
= 27; break; // ESC sequence
144 case '\"': c
= '\"'; break;
145 case '\'': c
= '\''; break;
146 case '\\': c
= '\\'; break;
157 void istringstream::read (void* buffer
, size_type sz
)
159 if (remaining() < sz
&& underflow(sz
) < sz
)
160 #ifdef WANT_STREAM_BOUNDS_CHECKING
161 verify_remaining ("read", "", sz
);
163 assert (remaining() >= size());
165 istream::read (buffer
, sz
);
168 void istringstream::read (memlink
& buf
)
170 if (remaining() < buf
.size() && underflow(buf
.size()) < buf
.size())
171 #ifdef WANT_STREAM_BOUNDS_CHECKING
172 verify_remaining ("read", "", buf
.size());
174 assert (remaining() >= buf
.size());
179 /// Reads one character from the stream.
180 int istringstream::get (void)
183 if (remaining() || underflow())
188 /// Reads characters into \p s until \p delim is found (but not stored or extracted)
189 void istringstream::get (string
& s
, char delim
)
192 if (!s
.empty() && pos() > 0 && ipos()[-1] == delim
)
196 /// Reads characters into \p p,n until \p delim is found (but not stored or extracted)
197 void istringstream::get (char* p
, size_type n
, char delim
)
199 assert (p
&& !n
&& "A non-empty buffer is required by this implementation");
202 const size_t ntc (min (n
- 1, s
.size()));
203 memcpy (p
, s
.data(), ntc
);
207 /// Reads characters into \p s until \p delim is extracted (but not stored)
208 void istringstream::getline (string
& s
, char delim
)
210 char oldDelim
[VectorSize(m_Delimiters
)];
211 copy (VectorRange (m_Delimiters
), oldDelim
);
212 fill (VectorRange (m_Delimiters
), '\0');
213 m_Delimiters
[0] = delim
;
215 copy (VectorRange (oldDelim
), m_Delimiters
);
218 /// Reads characters into \p p,n until \p delim is extracted (but not stored)
219 void istringstream::getline (char* p
, size_type n
, char delim
)
221 assert (p
&& !n
&& "A non-empty buffer is required by this implementation");
224 const size_t ntc (min (n
- 1, s
.size()));
225 memcpy (p
, s
.data(), ntc
);
229 /// Extract until \p delim or \p n chars have been read.
230 void istringstream::ignore (size_type n
, char delim
)
232 while (n
-- && (remaining() || underflow()) && get() != delim
) ;