]> git.saurik.com Git - wxWidgets.git/blame - src/common/txtstrm.cpp
wxString::FormatV() fix (bug 416853)
[wxWidgets.git] / src / common / txtstrm.cpp
CommitLineData
5a96d2f4 1///////////////////////////////////////////////////////////////////////////////
fae05df5
GL
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$
717b9bf2 8// Copyright: (c) Guilhem Lavaux
cd6ce4a9 9// Licence: wxWindows license
fae05df5
GL
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "txtstrm.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20 #pragma hdrstop
21#endif
22
23#if wxUSE_STREAMS
24
25#include "wx/txtstrm.h"
c980c992 26#include <ctype.h>
fae05df5 27
cd25b18c
RR
28
29// ----------------------------------------------------------------------------
30// constants
31// ----------------------------------------------------------------------------
32
33// Unix: "\n"
34// Dos: "\r\n"
35// Mac: "\r"
36
37// ----------------------------------------------------------------------------
38// wxTextInputStream
39// ----------------------------------------------------------------------------
40
191549ed
SB
41wxTextInputStream::wxTextInputStream(wxInputStream &s, const wxString &sep)
42 : m_input(s), m_separators(sep)
fae05df5
GL
43{
44}
45
46wxTextInputStream::~wxTextInputStream()
47{
48}
49
191549ed 50wxChar wxTextInputStream::NextNonSeparators()
fae05df5 51{
cd25b18c
RR
52 wxChar c = (wxChar) 0;
53 for (;;)
54 {
cd6ce4a9 55 if (!m_input) return (wxChar) 0;
191549ed 56 c = m_input.GetC();
cd6ce4a9
VZ
57
58 if (c != wxT('\n') &&
59 c != wxT('\r') &&
60 !m_separators.Contains(c))
61 return c;
cd25b18c 62 }
717b9bf2 63
cd25b18c 64}
fae05df5 65
f6bcfd97 66bool wxTextInputStream::EatEOL(const wxChar &c)
cd25b18c 67{
f6bcfd97 68 if (c == wxT('\n')) return TRUE; // eat on UNIX
cd6ce4a9 69
f6bcfd97 70 if (c == wxT('\r')) // eat on both Mac and DOS
717b9bf2 71 {
f6bcfd97
BP
72 if (!m_input) return TRUE;
73 wxChar c2 = m_input.GetC();
cd6ce4a9 74
f6bcfd97
BP
75 if (c2 != wxT('\n')) m_input.Ungetch( c2 ); // Don't eat on Mac
76 return TRUE;
cd25b18c 77 }
717b9bf2 78
f6bcfd97 79 return FALSE;
191549ed
SB
80}
81
82void wxTextInputStream::SkipIfEndOfLine( wxChar c )
83{
84 if (EatEOL(c)) return;
85 else m_input.Ungetch( c ); // no line terminator
cd25b18c 86}
fae05df5 87
cd25b18c
RR
88wxUint32 wxTextInputStream::Read32()
89{
90 /* I only implemented a simple integer parser */
cd6ce4a9
VZ
91 // VZ: what about using strtol()?? (TODO)
92
cd25b18c
RR
93 int sign;
94 wxInt32 i;
717b9bf2 95
cd25b18c 96 if (!m_input) return 0;
cd6ce4a9 97 int c = NextNonSeparators();
191549ed 98 if (c==(wxChar)0) return 0;
cd25b18c
RR
99
100 i = 0;
223d09f6 101 if (! (c == wxT('-') || c == wxT('+') || isdigit(c)) )
cd25b18c 102 {
191549ed 103 m_input.Ungetch(c);
cd25b18c
RR
104 return 0;
105 }
fae05df5 106
223d09f6 107 if (c == wxT('-'))
cd25b18c
RR
108 {
109 sign = -1;
191549ed 110 c = m_input.GetC();
717b9bf2 111 } else
223d09f6 112 if (c == wxT('+'))
cd25b18c
RR
113 {
114 sign = 1;
191549ed 115 c = m_input.GetC();
717b9bf2 116 } else
cd25b18c
RR
117 {
118 sign = 1;
119 }
fae05df5 120
717b9bf2 121 while (isdigit(c))
cd25b18c 122 {
223d09f6 123 i = i*10 + (c - (int)wxT('0'));
191549ed 124 c = m_input.GetC();
cd25b18c 125 }
fae05df5 126
cd25b18c 127 SkipIfEndOfLine( c );
fae05df5 128
cd25b18c 129 i *= sign;
fae05df5 130
cd25b18c 131 return (wxUint32)i;
fae05df5
GL
132}
133
134wxUint16 wxTextInputStream::Read16()
135{
cd25b18c 136 return (wxUint16)Read32();
fae05df5
GL
137}
138
139wxUint8 wxTextInputStream::Read8()
140{
cd25b18c 141 return (wxUint8)Read32();
fae05df5
GL
142}
143
144double wxTextInputStream::ReadDouble()
145{
f6bcfd97
BP
146 /* I only implemented a simple float parser
147 * VZ: what about using strtod()?? (TODO)
148 */
149
cd25b18c 150 double f;
f6bcfd97
BP
151 int theSign;
152
153 if (!m_input)
154 return 0;
cd25b18c 155
191549ed
SB
156 int c = NextNonSeparators();
157 if (c==(wxChar)0) return 0;
cd25b18c
RR
158
159 f = 0.0;
78e848ca 160 if (! (c == wxT('.') || c == wxT(',') || c == wxT('-') || c == wxT('+') || isdigit(c)) )
cd25b18c 161 {
191549ed 162 m_input.Ungetch(c);
f6bcfd97 163 return 0;
cd25b18c
RR
164 }
165
223d09f6 166 if (c == wxT('-'))
cd25b18c 167 {
f6bcfd97 168 theSign = -1;
191549ed 169 c = m_input.GetC();
717b9bf2 170 } else
223d09f6 171 if (c == wxT('+'))
cd25b18c 172 {
f6bcfd97 173 theSign = 1;
191549ed 174 c = m_input.GetC();
717b9bf2
DW
175 }
176 else
cd25b18c 177 {
f6bcfd97 178 theSign = 1;
cd25b18c
RR
179 }
180
717b9bf2 181 while (isdigit(c))
cd25b18c 182 {
223d09f6 183 f = f*10 + (c - wxT('0'));
191549ed 184 c = m_input.GetC();
fae05df5
GL
185 }
186
78e848ca 187 if (c == wxT('.') || c == wxT(','))
cd25b18c
RR
188 {
189 double f_multiplicator = (double) 0.1;
fae05df5 190
191549ed 191 c = m_input.GetC();
fae05df5 192
717b9bf2 193 while (isdigit(c))
cd6ce4a9 194 {
223d09f6 195 f += (c-wxT('0'))*f_multiplicator;
cd25b18c 196 f_multiplicator /= 10;
191549ed 197 c = m_input.GetC();
cd25b18c 198 }
fae05df5 199
223d09f6 200 if (c == wxT('e'))
cd6ce4a9 201 {
cd25b18c
RR
202 double f_multiplicator = 0.0;
203 int i, e;
fae05df5 204
191549ed 205 c = m_input.GetC();
fae05df5 206
717b9bf2 207 switch (c)
cd6ce4a9 208 {
223d09f6 209 case wxT('-'): f_multiplicator = 0.1; break;
cd6ce4a9
VZ
210 case wxT('+'): f_multiplicator = 10.0; break;
211 }
fae05df5 212
cd25b18c
RR
213 e = Read8(); // why only max 256 ?
214
215 for (i=0;i<e;i++)
216 f *= f_multiplicator;
717b9bf2 217 }
cd6ce4a9
VZ
218 else
219 SkipIfEndOfLine( c );
cd25b18c
RR
220 }
221 else
222 {
191549ed 223 m_input.Ungetch(c);
cd25b18c
RR
224 }
225
f6bcfd97 226 f *= theSign;
cd25b18c 227 return f;
fae05df5
GL
228}
229
230wxString wxTextInputStream::ReadString()
9853d977 231{
cd6ce4a9 232 return ReadLine();
9853d977
SB
233}
234
235wxString wxTextInputStream::ReadLine()
fae05df5 236{
cd25b18c
RR
237 wxChar c;
238 wxString line;
239
cd6ce4a9 240 while ( !m_input.Eof() )
cd25b18c 241 {
191549ed 242 c = m_input.GetC();
f6bcfd97 243
cd6ce4a9
VZ
244 if ( !m_input )
245 break;
246
247 if (EatEOL(c))
248 break;
249
cd25b18c
RR
250 line += c;
251 }
717b9bf2 252
cd25b18c 253 return line;
fae05df5 254}
717b9bf2 255
9853d977
SB
256wxString wxTextInputStream::ReadWord()
257{
9853d977 258 wxString word;
9853d977 259
cd6ce4a9
VZ
260 if ( !m_input )
261 return word;
262
263 wxChar c = NextNonSeparators();
264 if ( !c )
265 return word;
266
f6bcfd97
BP
267 word += c;
268
cd6ce4a9 269 while ( !m_input.Eof() )
9853d977 270 {
f6bcfd97
BP
271 c = m_input.GetC();
272
273 if (!m_input)
274 break;
275
cd6ce4a9
VZ
276 if (m_separators.Contains(c))
277 break;
278
279 if (EatEOL(c))
280 break;
281
9853d977 282 word += c;
9853d977
SB
283 }
284
285 return word;
286}
287
288wxTextInputStream& wxTextInputStream::operator>>(wxString& word)
fae05df5 289{
cd6ce4a9
VZ
290 word = ReadWord();
291 return *this;
fae05df5
GL
292}
293
f6bcfd97 294wxTextInputStream& wxTextInputStream::operator>>(char& c)
fae05df5 295{
cd25b18c
RR
296 if (!m_input)
297 {
f6bcfd97 298 c = 0;
cd25b18c
RR
299 return *this;
300 }
717b9bf2 301
191549ed 302 c = m_input.GetC();
717b9bf2 303
f6bcfd97
BP
304 if (EatEOL(c))
305 c = '\n';
306
cd25b18c 307 return *this;
fae05df5
GL
308}
309
310wxTextInputStream& wxTextInputStream::operator>>(wxInt16& i)
311{
cd25b18c
RR
312 i = (wxInt16)Read16();
313 return *this;
fae05df5
GL
314}
315
316wxTextInputStream& wxTextInputStream::operator>>(wxInt32& i)
317{
cd25b18c
RR
318 i = (wxInt32)Read32();
319 return *this;
fae05df5
GL
320}
321
fae05df5
GL
322wxTextInputStream& wxTextInputStream::operator>>(wxUint16& i)
323{
cd25b18c
RR
324 i = Read16();
325 return *this;
fae05df5
GL
326}
327
328wxTextInputStream& wxTextInputStream::operator>>(wxUint32& i)
329{
cd25b18c
RR
330 i = Read32();
331 return *this;
fae05df5
GL
332}
333
334wxTextInputStream& wxTextInputStream::operator>>(double& i)
335{
cd25b18c
RR
336 i = ReadDouble();
337 return *this;
fae05df5
GL
338}
339
340wxTextInputStream& wxTextInputStream::operator>>(float& f)
341{
cd25b18c
RR
342 f = (float)ReadDouble();
343 return *this;
fae05df5
GL
344}
345
c7a9fa36 346wxTextOutputStream::wxTextOutputStream(wxOutputStream& s, wxEOL mode)
191549ed 347 : m_output(s)
fae05df5 348{
c7a9fa36
RR
349 m_mode = mode;
350 if (m_mode == wxEOL_NATIVE)
351 {
352#if defined(__WXMSW__) || defined(__WXPM__)
353 m_mode = wxEOL_DOS;
354#elif defined(__WXMAC__)
355 m_mode = wxEOL_MAC;
356#else
357 m_mode = wxEOL_UNIX;
358#endif
359 }
fae05df5
GL
360}
361
362wxTextOutputStream::~wxTextOutputStream()
363{
364}
365
cd0b1709 366void wxTextOutputStream::SetMode(wxEOL mode)
c7a9fa36
RR
367{
368 m_mode = mode;
369 if (m_mode == wxEOL_NATIVE)
370 {
371#if defined(__WXMSW__) || defined(__WXPM__)
372 m_mode = wxEOL_DOS;
373#elif defined(__WXMAC__)
374 m_mode = wxEOL_MAC;
375#else
376 m_mode = wxEOL_UNIX;
377#endif
378 }
379}
380
fae05df5
GL
381void wxTextOutputStream::Write32(wxUint32 i)
382{
cd25b18c 383 wxString str;
223d09f6 384 str.Printf(wxT("%u"), i);
717b9bf2 385
cd25b18c 386 WriteString(str);
fae05df5
GL
387}
388
389void wxTextOutputStream::Write16(wxUint16 i)
390{
cd25b18c 391 wxString str;
223d09f6 392 str.Printf(wxT("%u"), i);
717b9bf2 393
cd25b18c 394 WriteString(str);
fae05df5
GL
395}
396
397void wxTextOutputStream::Write8(wxUint8 i)
398{
cd25b18c 399 wxString str;
223d09f6 400 str.Printf(wxT("%u"), i);
717b9bf2 401
cd25b18c 402 WriteString(str);
fae05df5
GL
403}
404
405void wxTextOutputStream::WriteDouble(double d)
406{
cd25b18c 407 wxString str;
fae05df5 408
223d09f6 409 str.Printf(wxT("%f"), d);
cd25b18c 410 WriteString(str);
fae05df5
GL
411}
412
413void wxTextOutputStream::WriteString(const wxString& string)
414{
cd25b18c
RR
415 for (size_t i = 0; i < string.Len(); i++)
416 {
417 wxChar c = string[i];
223d09f6 418 if (c == wxT('\n'))
cd25b18c 419 {
cd6ce4a9
VZ
420 if (m_mode == wxEOL_DOS)
421 {
c7a9fa36
RR
422 c = wxT('\r');
423 m_output.Write( (const void*)(&c), sizeof(wxChar) );
424 c = wxT('\n');
425 m_output.Write( (const void*)(&c), sizeof(wxChar) );
cd6ce4a9
VZ
426 } else
427 if (m_mode == wxEOL_MAC)
428 {
c7a9fa36
RR
429 c = wxT('\r');
430 m_output.Write( (const void*)(&c), sizeof(wxChar) );
cd6ce4a9
VZ
431 } else
432 {
c7a9fa36
RR
433 c = wxT('\n');
434 m_output.Write( (const void*)(&c), sizeof(wxChar) );
435 }
cd25b18c
RR
436 }
437 else
438 {
191549ed 439 m_output.Write( (const void*)(&c), sizeof(wxChar) );
cd25b18c
RR
440 }
441 }
fae05df5
GL
442}
443
444wxTextOutputStream& wxTextOutputStream::operator<<(const wxChar *string)
445{
cd25b18c
RR
446 WriteString( wxString(string) );
447 return *this;
fae05df5
GL
448}
449
450wxTextOutputStream& wxTextOutputStream::operator<<(const wxString& string)
451{
cd25b18c
RR
452 WriteString( string );
453 return *this;
fae05df5
GL
454}
455
f6bcfd97 456wxTextOutputStream& wxTextOutputStream::operator<<(char c)
fae05df5 457{
f6bcfd97
BP
458 // these strange manipulations are needed in Unicode mode
459 char buf[2];
460 buf[0] = c;
461 buf[1] = 0;
462
463 WriteString( wxString(buf) );
cd25b18c 464 return *this;
fae05df5
GL
465}
466
467wxTextOutputStream& wxTextOutputStream::operator<<(wxInt16 c)
468{
78e848ca
RR
469 wxString str;
470 str.Printf(wxT("%d"), (signed int)c);
471 WriteString(str);
cd6ce4a9 472
cd25b18c 473 return *this;
fae05df5
GL
474}
475
476wxTextOutputStream& wxTextOutputStream::operator<<(wxInt32 c)
477{
78e848ca
RR
478 wxString str;
479 str.Printf(wxT("%ld"), (signed long)c);
480 WriteString(str);
cd6ce4a9 481
cd25b18c 482 return *this;
fae05df5
GL
483}
484
fae05df5
GL
485wxTextOutputStream& wxTextOutputStream::operator<<(wxUint16 c)
486{
78e848ca
RR
487 wxString str;
488 str.Printf(wxT("%u"), (unsigned int)c);
489 WriteString(str);
cd6ce4a9 490
cd25b18c 491 return *this;
fae05df5
GL
492}
493
494wxTextOutputStream& wxTextOutputStream::operator<<(wxUint32 c)
495{
78e848ca
RR
496 wxString str;
497 str.Printf(wxT("%lu"), (unsigned long)c);
498 WriteString(str);
499
cd25b18c 500 return *this;
fae05df5
GL
501}
502
503wxTextOutputStream &wxTextOutputStream::operator<<(double f)
504{
cd25b18c
RR
505 WriteDouble(f);
506 return *this;
fae05df5
GL
507}
508
509wxTextOutputStream& wxTextOutputStream::operator<<(float f)
510{
cd25b18c
RR
511 WriteDouble((double)f);
512 return *this;
fae05df5
GL
513}
514
ed58dbea
RR
515wxTextOutputStream &endl( wxTextOutputStream &stream )
516{
223d09f6 517 return stream << wxT('\n');
ed58dbea
RR
518}
519
fae05df5
GL
520#endif
521 // wxUSE_STREAMS