Exemplo n.º 1
0
bool MfStatusCache::DoLoad(const wxTextFile& file, int version)
{
   bool isFmtOk = true;

   CacheFileFormat fmt;
   if ( version == BuildVersion(1, 1) )
   {
      fmt = CacheFile_1_1;
   }
   else if ( version == BuildVersion(1, 0) )
   {
      fmt = CacheFile_1_0;
   }
   else
   {
      fmt = CacheFile_Max;
   }

   // read the data
   wxString str, name;
   str.Alloc(1024);     // avoid extra memory allocations
   name.Alloc(1024);

   MailFolderStatus status;

   size_t count = file.GetLineCount();
   for ( size_t n = 1; n < count; n++ )
   {
      str = file[n];

      // first get the end of the full folder name knowing that we should
      // skip all "::" as they could have only resulted from quoting a ':'
      // in the folder name and so the loop below looks for the first ':'
      // not followed by another ':'
      const wxChar *p = wxStrchr(str, CACHE_DELIMITER_CH);
      while ( p && p[1] == CACHE_DELIMITER_CH )
      {
         p = wxStrchr(p + 2, CACHE_DELIMITER_CH);
      }

      if ( !p )
      {
         wxLogError(_("Missing '%c' at line %d."), CACHE_DELIMITER_CH, n + 1);

         isFmtOk = false;

         break;
      }

      name = wxString(str.c_str(), p);

      // now unquote ':' which were doubled by Save()
      name.Replace(CACHE_DELIMITER CACHE_DELIMITER, CACHE_DELIMITER);

      // get the rest
      status.Init();
      switch ( fmt )
      {
         case CacheFile_1_0:
            isFmtOk = wxSscanf(p + 1,
                             _T("%lu") CACHE_DELIMITER
                             _T("%lu") CACHE_DELIMITER
                             _T("%lu"),
                             &status.total,
                             &status.unread,
                             &status.flagged) == 3;
            break;

         default:
            FAIL_MSG( _T("unknown cache file format") );
            // fall through nevertheless

         case CacheFile_1_1:
            isFmtOk = wxSscanf(p + 1,
                             _T("%lu") CACHE_DELIMITER
                             _T("%lu") CACHE_DELIMITER 
                             _T("%lu") CACHE_DELIMITER
                             _T("%lu"),
                             &status.total,
                             &status.newmsgs,
                             &status.unread,
                             &status.flagged) == 4;
      }

      if ( !isFmtOk )
      {
         wxLogError(_("Missing field(s) at line %d."), n + 1);

         break;
      }

      // ignore the folders which were deleted during the last program run
      MFolder *folder = MFolder::Get(name);
      if ( folder )
      {
         folder->DecRef();

         // do add the entry to the cache
         size_t entry = m_folderNames.Add(name);
         m_folderData.Insert(new MailFolderStatus(status), entry);
      }
      else
      {
         wxLogDebug(_T("Removing deleted folder '%s' from status cache."),
                    name.c_str());
      }
   }

   if ( !isFmtOk )
   {
      wxLogWarning(_("Your mail folder status cache file (%s) was corrupted."),
                   file.GetName());

      return false;
   }

   return true;
}
Exemplo n.º 2
0
void wxFileConfig::Parse(wxTextFile& file, bool bLocal)
{
  const wxChar *pStart;
  const wxChar *pEnd;
  wxString strLine;

  size_t nLineCount = file.GetLineCount();
  for ( size_t n = 0; n < nLineCount; n++ ) {
    strLine = file[n];

    // add the line to linked list
    if ( bLocal )
      LineListAppend(strLine);

    // skip leading spaces
    for ( pStart = strLine; wxIsspace(*pStart); pStart++ )
      ;

    // skip blank/comment lines
    if ( *pStart == wxT('\0')|| *pStart == wxT(';') || *pStart == wxT('#') )
      continue;

    if ( *pStart == wxT('[') ) {          // a new group
      pEnd = pStart;

      while ( *++pEnd != wxT(']') ) {
        if ( *pEnd == wxT('\\') ) {
            // the next char is escaped, so skip it even if it is ']'
            pEnd++;
        }

        if ( *pEnd == wxT('\n') || *pEnd == wxT('\0') ) {
            // we reached the end of line, break out of the loop
            break;
        }
      }

      if ( *pEnd != wxT(']') ) {
        wxLogError(_("file '%s': unexpected character %c at line %d."),
                   file.GetName(), *pEnd, n + 1);
        continue; // skip this line
      }

      // group name here is always considered as abs path
      wxString strGroup;
      pStart++;
      strGroup << wxCONFIG_PATH_SEPARATOR
               << FilterInEntryName(wxString(pStart, pEnd - pStart));

      // will create it if doesn't yet exist
      SetPath(strGroup);

      if ( bLocal )
        m_pCurrentGroup->SetLine(m_linesTail);

      // check that there is nothing except comments left on this line
      bool bCont = TRUE;
      while ( *++pEnd != wxT('\0') && bCont ) {
        switch ( *pEnd ) {
          case wxT('#'):
          case wxT(';'):
            bCont = FALSE;
            break;

          case wxT(' '):
          case wxT('\t'):
            // ignore whitespace ('\n' impossible here)
            break;

          default:
            wxLogWarning(_("file '%s', line %d: '%s' ignored after group header."),
                         file.GetName(), n + 1, pEnd);
            bCont = FALSE;
        }
      }
    }
    else {                        // a key
      const wxChar *pEnd = pStart;
      while ( *pEnd && *pEnd != wxT('=') && !wxIsspace(*pEnd) ) {
        if ( *pEnd == wxT('\\') ) {
          // next character may be space or not - still take it because it's
          // quoted (unless there is nothing)
          pEnd++;
          if ( !*pEnd ) {
            // the error message will be given below anyhow
            break;
          }
        }

        pEnd++;
      }

      wxString strKey(FilterInEntryName(wxString(pStart, pEnd)));

      // skip whitespace
      while ( wxIsspace(*pEnd) )
        pEnd++;

      if ( *pEnd++ != wxT('=') ) {
        wxLogError(_("file '%s', line %d: '=' expected."),
                   file.GetName(), n + 1);
      }
      else {
        ConfigEntry *pEntry = m_pCurrentGroup->FindEntry(strKey);

        if ( pEntry == NULL ) {
          // new entry
          pEntry = m_pCurrentGroup->AddEntry(strKey, n);

          if ( bLocal )
            pEntry->SetLine(m_linesTail);
        }
        else {
          if ( bLocal && pEntry->IsImmutable() ) {
            // immutable keys can't be changed by user
            wxLogWarning(_("file '%s', line %d: value for immutable key '%s' ignored."),
                         file.GetName(), n + 1, strKey.c_str());
            continue;
          }
          // the condition below catches the cases (a) and (b) but not (c):
          //  (a) global key found second time in global file
          //  (b) key found second (or more) time in local file
          //  (c) key from global file now found in local one
          // which is exactly what we want.
          else if ( !bLocal || pEntry->IsLocal() ) {
            wxLogWarning(_("file '%s', line %d: key '%s' was first found at line %d."),
                         file.GetName(), n + 1, strKey.c_str(), pEntry->Line());

            if ( bLocal )
              pEntry->SetLine(m_linesTail);
          }
        }

        // skip whitespace
        while ( wxIsspace(*pEnd) )
          pEnd++;
        
        if ( GetStyle() & wxCONFIG_USE_NO_ESCAPE_CHARACTERS )
            pEntry->SetValue(pEnd, FALSE /* read from file, without escapes */);
        else
            pEntry->SetValue(FilterInValue(pEnd), FALSE /* read from file, with escapes */);
        
        //pEntry->SetValue(FilterInValue(pEnd), FALSE /* read from file */);
      }
    }
  }
}