home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / common / txtstrm.cpp < prev    next >
C/C++ Source or Header  |  2002-11-04  |  11KB  |  556 lines

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