]>
git.saurik.com Git - wxWidgets.git/blob - src/common/textfile.cpp
0a01a6e70e463d8d41ea2d185d994d5ffad89458
   1 /////////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     implementation of wxTextFile class 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> 
   9 // Licence:     wxWindows license 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  17 #pragma implementation "textfile.h" 
  20 #include  "wx/wxprec.h" 
  26 #include  <wx/string.h> 
  30 #include  <wx/textfile.h> 
  32 // ============================================================================ 
  33 // wxTextFile class implementation 
  34 // ============================================================================ 
  36 // ---------------------------------------------------------------------------- 
  38 // ---------------------------------------------------------------------------- 
  40 // default type is the native one 
  41 const wxTextFile::Type 
wxTextFile::typeDefault 
= wxTextFile:: 
  42 #if   defined(__WINDOWS__) 
  44 #elif defined(__UNIX__) 
  46 #elif defined(__WXMAC__) 
  50   #error  "wxTextFile: unsupported platform." 
  54 // ---------------------------------------------------------------------------- 
  56 // ---------------------------------------------------------------------------- 
  58 wxTextFile::wxTextFile(const wxString
& strFile
) : m_strFile(strFile
) 
  62 wxTextFile::~wxTextFile() 
  64   // m_file dtor called automatically 
  67 // ---------------------------------------------------------------------------- 
  69 // ---------------------------------------------------------------------------- 
  71 bool wxTextFile::Open(const wxString
& strFile
) 
  77 bool wxTextFile::Open() 
  79   // file name must be either given in ctor or in Open(const wxString&) 
  80   wxASSERT( !m_strFile
.IsEmpty() ); 
  82   // open file in read-only mode 
  83   if ( !m_file
.Open(m_strFile
) ) 
  86   // read file into memory 
  94 // analyse some lines of the file trying to guess it's type. 
  95 // if it fails, it assumes the native type for our platform. 
  96 wxTextFile::Type 
wxTextFile::GuessType() const 
  98   // file should be opened and we must be in it's beginning 
  99   wxASSERT( m_file
.IsOpened() && m_file
.Tell() == 0 ); 
 101   // scan the file lines 
 102   size_t nUnix 
= 0,     // number of '\n's alone 
 103        nDos  
= 0,     // number of '\r\n' 
 104        nMac  
= 0;     // number of '\r's 
 106   // we take MAX_LINES_SCAN in the beginning, middle and the end of file 
 107   #define MAX_LINES_SCAN    (10) 
 108   size_t nCount 
= m_aLines
.Count() / 3, 
 109        nScan 
=  nCount 
> 3*MAX_LINES_SCAN 
? MAX_LINES_SCAN 
: nCount 
/ 3; 
 111   #define   AnalyseLine(n)              \ 
 112     switch ( m_aTypes[n] ) {            \ 
 113       case Type_Unix: nUnix++; break;   \ 
 114       case Type_Dos:  nDos++;  break;   \ 
 115       case Type_Mac:  nMac++;  break;   \ 
 116       default: wxFAIL_MSG(_("unknown line terminator")); \ 
 120   for ( n 
= 0; n 
< nScan
; n
++ )     // the beginning 
 122   for ( n 
= (nCount 
- nScan
)/2; n 
< (nCount 
+ nScan
)/2; n
++ ) 
 124   for ( n 
= nCount 
- nScan
; n 
< nCount
; n
++ ) 
 129   // interpret the results (@@ far from being even 50% fool proof) 
 130   if ( nDos 
+ nUnix 
+ nMac 
== 0 ) { 
 131     // no newlines at all 
 132     wxLogWarning(_("'%s' is probably a binary file."), m_strFile
.c_str()); 
 135     #define   GREATER_OF(t1, t2) n##t1 == n##t2 ? typeDefault               \ 
 136                                                 : n##t1 > n##t2 ? Type_##t1 \ 
 139 // Watcom C++ doesn't seem to be able to handle the macro 
 140 #if defined(__WATCOMC__) 
 144       return GREATER_OF(Dos
, Mac
); 
 145     else if ( nDos 
< nUnix 
) 
 146       return GREATER_OF(Unix
, Mac
); 
 149       return nMac 
> nDos 
? Type_Mac 
: typeDefault
; 
 159 bool wxTextFile::Read() 
 161   // file should be opened and we must be in it's beginning 
 162   wxASSERT( m_file
.IsOpened() && m_file
.Tell() == 0 ); 
 165   char ch
, chLast 
= '\0'; 
 168   while ( !m_file
.Eof() ) { 
 169     nRead 
= m_file
.Read(buf
, WXSIZEOF(buf
)); 
 170     if ( nRead 
== wxInvalidOffset 
) { 
 171       // read error (error message already given in wxFile::Read) 
 176     for ( n 
= 0; n 
< nRead
; n
++ ) { 
 180           // Dos/Unix line termination 
 182           m_aTypes
.Add(chLast 
== '\r' ? Type_Dos 
: Type_Unix
); 
 188           if ( chLast 
== '\r' ) { 
 191             m_aTypes
.Add(Type_Mac
); 
 198           if ( chLast 
== '\r' ) { 
 199             // Mac line termination 
 201             m_aTypes
.Add(Type_Mac
); 
 206             // add to the current line 
 213   // anything in the last line? 
 214   if ( !str
.IsEmpty() ) { 
 215     m_aTypes
.Add(Type_None
);  // no line terminator 
 222 bool wxTextFile::Write(Type typeNew
) 
 224   wxTempFile 
fileTmp(m_strFile
); 
 226   if ( !fileTmp
.IsOpened() ) { 
 227     wxLogError(_("can't write file '%s' to disk."), m_strFile
.c_str()); 
 231   size_t nCount 
= m_aLines
.Count(); 
 232   for ( size_t n 
= 0; n 
< nCount
; n
++ ) { 
 233     fileTmp
.Write(m_aLines
[n
] + 
 234                   GetEOL(typeNew 
== Type_None 
? m_aTypes
[n
] : typeNew
)); 
 237   // replace the old file with this one 
 238   return fileTmp
.Commit(); 
 241 const char *wxTextFile::GetEOL(Type type
) 
 244       case Type_None
: return ""; 
 245       case Type_Unix
: return "\n"; 
 246       case Type_Dos
:  return "\r\n"; 
 247       case Type_Mac
:  return "\r"; 
 250         wxFAIL_MSG("bad file type in wxTextFile::GetEOL."); 
 251         return (const char *) NULL
;