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