]> git.saurik.com Git - wxWidgets.git/blob - src/common/txtstrm.cpp
Improved size handling.
[wxWidgets.git] / src / common / txtstrm.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: txtstrm.cpp
3 // Purpose: Text stream classes
4 // Author: Guilhem Lavaux
5 // Modified by:
6 // Created: 28/06/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #if wxUSE_STREAMS
20
21 #include "wx/txtstrm.h"
22 #include <ctype.h>
23
24
25 // ----------------------------------------------------------------------------
26 // constants
27 // ----------------------------------------------------------------------------
28
29 // Unix: "\n"
30 // Dos: "\r\n"
31 // Mac: "\r"
32
33 // ----------------------------------------------------------------------------
34 // wxTextInputStream
35 // ----------------------------------------------------------------------------
36
37 #if wxUSE_UNICODE
38 wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep, wxMBConv& conv)
39 : m_input(s), m_separators(sep), m_conv(conv)
40 {
41 memset((void*)m_lastBytes, 0, 10);
42 }
43 #else
44 wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep)
45 : m_input(s), m_separators(sep)
46 {
47 memset((void*)m_lastBytes, 0, 10);
48 }
49 #endif
50
51 wxTextInputStream::~wxTextInputStream()
52 {
53 }
54
55 void wxTextInputStream::UngetLast()
56 {
57 size_t byteCount = 0;
58 while(m_lastBytes[byteCount]) // pseudo ANSI strlen (even for Unicode!)
59 byteCount++;
60 m_input.Ungetch(m_lastBytes, byteCount);
61 memset((void*)m_lastBytes, 0, 10);
62 }
63
64 wxChar wxTextInputStream::NextChar()
65 {
66 #if wxUSE_UNICODE
67 wxChar wbuf[2];
68 memset((void*)m_lastBytes, 0, 10);
69 for(size_t inlen = 0; inlen < 9; inlen++)
70 {
71 // actually read the next character
72 m_lastBytes[inlen] = m_input.GetC();
73
74 if(m_input.LastRead() <= 0)
75 return wxEOT;
76
77 int retlen = (int) m_conv.MB2WC(wbuf, m_lastBytes, 2); // returns -1 for failure
78 if(retlen >= 0) // res == 0 could happen for '\0' char
79 return wbuf[0];
80 }
81 // there should be no encoding which requires more than nine bytes for one character...
82 return wxEOT;
83 #else
84 m_lastBytes[0] = m_input.GetC();
85
86 if(m_input.LastRead() <= 0)
87 return wxEOT;
88
89 return m_lastBytes[0];
90 #endif
91
92 }
93
94 wxChar wxTextInputStream::NextNonSeparators()
95 {
96 for (;;)
97 {
98 wxChar c = NextChar();
99 if (c == wxEOT) return (wxChar) 0;
100
101 if (c != wxT('\n') &&
102 c != wxT('\r') &&
103 !m_separators.Contains(c))
104 return c;
105 }
106
107 }
108
109 bool wxTextInputStream::EatEOL(const wxChar &c)
110 {
111 if (c == wxT('\n')) return true; // eat on UNIX
112
113 if (c == wxT('\r')) // eat on both Mac and DOS
114 {
115 wxChar c2 = NextChar();
116 if(c2 == wxEOT) return true; // end of stream reached, had enough :-)
117
118 if (c2 != wxT('\n')) UngetLast(); // Don't eat on Mac
119 return true;
120 }
121
122 return false;
123 }
124
125 wxUint32 wxTextInputStream::Read32(int base)
126 {
127 wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") );
128 if(!m_input) return 0;
129
130 wxString word = ReadWord();
131 if(word.empty())
132 return 0;
133 return wxStrtoul(word.c_str(), 0, base);
134 }
135
136 wxUint16 wxTextInputStream::Read16(int base)
137 {
138 return (wxUint16)Read32(base);
139 }
140
141 wxUint8 wxTextInputStream::Read8(int base)
142 {
143 return (wxUint8)Read32(base);
144 }
145
146 wxInt32 wxTextInputStream::Read32S(int base)
147 {
148 wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") );
149 if(!m_input) return 0;
150
151 wxString word = ReadWord();
152 if(word.empty())
153 return 0;
154 return wxStrtol(word.c_str(), 0, base);
155 }
156
157 wxInt16 wxTextInputStream::Read16S(int base)
158 {
159 return (wxInt16)Read32S(base);
160 }
161
162 wxInt8 wxTextInputStream::Read8S(int base)
163 {
164 return (wxInt8)Read32S(base);
165 }
166
167 double wxTextInputStream::ReadDouble()
168 {
169 if(!m_input) return 0;
170 wxString word = ReadWord();
171 if(word.empty())
172 return 0;
173 return wxStrtod(word.c_str(), 0);
174 }
175
176 wxString wxTextInputStream::ReadString()
177 {
178 return ReadLine();
179 }
180
181 wxString wxTextInputStream::ReadLine()
182 {
183 wxString line;
184
185 while ( !m_input.Eof() )
186 {
187 wxChar c = NextChar();
188 if(c == wxEOT)
189 break;
190
191 if ( !m_input )
192 break;
193
194 if (EatEOL(c))
195 break;
196
197 line += c;
198 }
199
200 return line;
201 }
202
203 wxString wxTextInputStream::ReadWord()
204 {
205 wxString word;
206
207 if ( !m_input )
208 return word;
209
210 wxChar c = NextNonSeparators();
211 if ( !c )
212 return word;
213
214 word += c;
215
216 while ( !m_input.Eof() )
217 {
218 c = NextChar();
219 if(c == wxEOT)
220 break;
221
222 if (m_separators.Contains(c))
223 break;
224
225 if (EatEOL(c))
226 break;
227
228 word += c;
229 }
230
231 return word;
232 }
233
234 wxTextInputStream& wxTextInputStream::operator>>(wxString& word)
235 {
236 word = ReadWord();
237 return *this;
238 }
239
240 wxTextInputStream& wxTextInputStream::operator>>(char& c)
241 {
242 c = m_input.GetC();
243 if(m_input.LastRead() <= 0) c = 0;
244
245 if (EatEOL(c))
246 c = '\n';
247
248 return *this;
249 }
250
251 #if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
252
253 wxTextInputStream& wxTextInputStream::operator>>(wchar_t& wc)
254 {
255 wc = GetChar();
256
257 return *this;
258 }
259
260 #endif // wxUSE_UNICODE
261
262 wxTextInputStream& wxTextInputStream::operator>>(wxInt16& i)
263 {
264 i = (wxInt16)Read16();
265 return *this;
266 }
267
268 wxTextInputStream& wxTextInputStream::operator>>(wxInt32& i)
269 {
270 i = (wxInt32)Read32();
271 return *this;
272 }
273
274 wxTextInputStream& wxTextInputStream::operator>>(wxUint16& i)
275 {
276 i = Read16();
277 return *this;
278 }
279
280 wxTextInputStream& wxTextInputStream::operator>>(wxUint32& i)
281 {
282 i = Read32();
283 return *this;
284 }
285
286 wxTextInputStream& wxTextInputStream::operator>>(double& i)
287 {
288 i = ReadDouble();
289 return *this;
290 }
291
292 wxTextInputStream& wxTextInputStream::operator>>(float& f)
293 {
294 f = (float)ReadDouble();
295 return *this;
296 }
297
298
299
300 #if wxUSE_UNICODE
301 wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode, wxMBConv& conv)
302 : m_output(s), m_conv(conv)
303 #else
304 wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode)
305 : m_output(s)
306 #endif
307 {
308 m_mode = mode;
309 if (m_mode == wxEOL_NATIVE)
310 {
311 #if defined(__WXMSW__) || defined(__WXPM__)
312 m_mode = wxEOL_DOS;
313 #elif defined(__WXMAC__) && !defined(__DARWIN__)
314 m_mode = wxEOL_MAC;
315 #else
316 m_mode = wxEOL_UNIX;
317 #endif
318 }
319 }
320
321 wxTextOutputStream::~wxTextOutputStream()
322 {
323 }
324
325 void wxTextOutputStream::SetMode(wxEOL mode)
326 {
327 m_mode = mode;
328 if (m_mode == wxEOL_NATIVE)
329 {
330 #if defined(__WXMSW__) || defined(__WXPM__)
331 m_mode = wxEOL_DOS;
332 #elif defined(__WXMAC__) && !defined(__DARWIN__)
333 m_mode = wxEOL_MAC;
334 #else
335 m_mode = wxEOL_UNIX;
336 #endif
337 }
338 }
339
340 void wxTextOutputStream::Write32(wxUint32 i)
341 {
342 wxString str;
343 str.Printf(wxT("%u"), i);
344
345 WriteString(str);
346 }
347
348 void wxTextOutputStream::Write16(wxUint16 i)
349 {
350 wxString str;
351 str.Printf(wxT("%u"), (unsigned)i);
352
353 WriteString(str);
354 }
355
356 void wxTextOutputStream::Write8(wxUint8 i)
357 {
358 wxString str;
359 str.Printf(wxT("%u"), (unsigned)i);
360
361 WriteString(str);
362 }
363
364 void wxTextOutputStream::WriteDouble(double d)
365 {
366 wxString str;
367
368 str.Printf(wxT("%f"), d);
369 WriteString(str);
370 }
371
372 void wxTextOutputStream::WriteString(const wxString& string)
373 {
374 size_t len = string.length();
375
376 wxString out;
377 out.reserve(len);
378
379 for ( size_t i = 0; i < len; i++ )
380 {
381 const wxChar c = string[i];
382 if ( c == wxT('\n') )
383 {
384 switch ( m_mode )
385 {
386 case wxEOL_DOS:
387 out << _T("\r\n");
388 continue;
389
390 case wxEOL_MAC:
391 out << _T('\r');
392 continue;
393
394 default:
395 wxFAIL_MSG( _T("unknown EOL mode in wxTextOutputStream") );
396 // fall through
397
398 case wxEOL_UNIX:
399 // don't treat '\n' specially
400 ;
401 }
402 }
403
404 out << c;
405 }
406
407 // We must not write the trailing NULL here
408 #if wxUSE_UNICODE
409 wxCharBuffer buffer = m_conv.cWC2MB( out );
410 m_output.Write( (const char*) buffer, strlen( (const char*) buffer ) );
411 #else
412 m_output.Write(out.c_str(), out.length() );
413 #endif
414 }
415
416 wxTextOutputStream& wxTextOutputStream::PutChar(wxChar c)
417 {
418 #if wxUSE_UNICODE
419 WriteString( wxString(&c, m_conv, 1) );
420 #else
421 WriteString( wxString(&c, wxConvLocal, 1) );
422 #endif
423 return *this;
424 }
425
426 wxTextOutputStream& wxTextOutputStream::operator<<(const wxChar *string)
427 {
428 WriteString( wxString(string) );
429 return *this;
430 }
431
432 wxTextOutputStream& wxTextOutputStream::operator<<(const wxString& string)
433 {
434 WriteString( string );
435 return *this;
436 }
437
438 wxTextOutputStream& wxTextOutputStream::operator<<(char c)
439 {
440 WriteString( wxString::FromAscii(c) );
441
442 return *this;
443 }
444
445 #if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
446
447 wxTextOutputStream& wxTextOutputStream::operator<<(wchar_t wc)
448 {
449 WriteString( wxString(&wc, m_conv, 1) );
450
451 return *this;
452 }
453
454 #endif // wxUSE_UNICODE
455
456 wxTextOutputStream& wxTextOutputStream::operator<<(wxInt16 c)
457 {
458 wxString str;
459 str.Printf(wxT("%d"), (signed int)c);
460 WriteString(str);
461
462 return *this;
463 }
464
465 wxTextOutputStream& wxTextOutputStream::operator<<(wxInt32 c)
466 {
467 wxString str;
468 str.Printf(wxT("%ld"), (signed long)c);
469 WriteString(str);
470
471 return *this;
472 }
473
474 wxTextOutputStream& wxTextOutputStream::operator<<(wxUint16 c)
475 {
476 wxString str;
477 str.Printf(wxT("%u"), (unsigned int)c);
478 WriteString(str);
479
480 return *this;
481 }
482
483 wxTextOutputStream& wxTextOutputStream::operator<<(wxUint32 c)
484 {
485 wxString str;
486 str.Printf(wxT("%lu"), (unsigned long)c);
487 WriteString(str);
488
489 return *this;
490 }
491
492 wxTextOutputStream &wxTextOutputStream::operator<<(double f)
493 {
494 WriteDouble(f);
495 return *this;
496 }
497
498 wxTextOutputStream& wxTextOutputStream::operator<<(float f)
499 {
500 WriteDouble((double)f);
501 return *this;
502 }
503
504 wxTextOutputStream &endl( wxTextOutputStream &stream )
505 {
506 return stream.PutChar(wxT('\n'));
507 }
508
509 #endif
510 // wxUSE_STREAMS