⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nucleusconfig.cxx

📁 opal的ptlib c++源程序 可以从官方网站上下载
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 * config.cxx
 *
 * System/application configuration class implementation
 *
 * Portable Windows Library
 *
 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * $Revision: 19008 $
 * $Author: rjongbloed $
 * $Date: 2007-11-29 09:17:41 +0000 (Thu, 29 Nov 2007) $
 */

#define _CONFIG_CXX

#include <ptlib.h>


#include "../common/pconfig.cxx"


#define SYS_CONFIG_NAME		"pwlib"

#define	APP_CONFIG_DIR		".pwlib_config/"
#define	SYS_CONFIG_DIR		"/usr/local/pwlib/"

#define	EXTENSION		".ini"
#define	ENVIRONMENT_CONFIG_STR	"/\~~environment~~\/"

//
//  a single key/value pair
//
PDECLARE_CLASS (PXConfigValue, PCaselessString)
  public:
    PXConfigValue(const PString & theKey, const PString & theValue = "") 
      : PCaselessString(theKey), value(theValue) { }
    PString GetValue() const { return value; }
    void    SetValue(const PString & theValue) { value = theValue; }

  protected:
    PString  value;
};

//
//  a list of key/value pairs
//
PLIST (PXConfigSectionList, PXConfigValue);

//
//  a list of key value pairs, with a section name
//
PDECLARE_CLASS(PXConfigSection, PCaselessString)
  public:
    PXConfigSection(const PCaselessString & theName) 
      : PCaselessString(theName) { list.AllowDeleteObjects(); }

    PXConfigSectionList & GetList() { return list; }

  protected:
    PXConfigSectionList list;
};

//
// a list of sections
//

PDECLARE_LIST(PXConfig, PXConfigSection)
  public:
    PXConfig(int i = 0);

    void Wait()   { mutex.Wait(); }
    void Signal() { mutex.Signal(); }

    PBoolean ReadFromFile (const PFilePath & filename);
    void ReadFromEnvironment (char **envp);

    PBoolean WriteToFile(const PFilePath & filename);
    PBoolean Flush(const PFilePath & filename, PBoolean force);

    void SetDirty()   { dirty = PTrue; }

    PBoolean      AddInstance();
    PBoolean      RemoveInstance(const PFilePath & filename);

  protected:
    int       instanceCount;
    PMutex    mutex;
    PBoolean      dirty;
    PBoolean      saveOnExit;
};

//
// a dictionary of configurations, keyed by filename
//
PDECLARE_DICTIONARY(PXConfigDictionary, PFilePath, PXConfig)
  public:
    PXConfigDictionary(int dummy);
    ~PXConfigDictionary();
    PXConfig * GetFileConfigInstance(const PFilePath & key, const PFilePath & readKey);
    PXConfig * GetEnvironmentInstance();
    void RemoveInstance(PXConfig * instance);
    void WriteChangedInstances(PBoolean force);

  protected:
    PMutex        mutex;
    PXConfig    * environmentInstance;
    PThread     * writeThread;
    PSyncPointAck stopConfigWriteThread;
};


PDECLARE_CLASS(PXConfigWriteThread, PThread)
  public:
    PXConfigWriteThread(PSyncPointAck & stop);
    ~PXConfigWriteThread();
    void Main();
  private:
    PSyncPointAck & stop;
};


PXConfigDictionary * configDict;

#define	new PNEW

//////////////////////////////////////////////////////

void PProcess::CreateConfigFilesDictionary()
{
  configFiles = new PXConfigDictionary(0);
}


PXConfigWriteThread::PXConfigWriteThread(PSyncPointAck & s)
  : PThread(10000, AutoDeleteThread),
    stop(s)
{
  Resume();
}

PXConfigWriteThread::~PXConfigWriteThread()
{
  stop.Acknowledge();
}

void PXConfigWriteThread::Main()
{
  while (!stop.Wait(30000))  // if stop.Wait() returns PTrue, we are shutting down
    configDict->WriteChangedInstances(PFalse);   // check dictionary for items that need writing

  configDict->WriteChangedInstances(PTrue);
}



PXConfig::PXConfig(int)
{
  // make sure content gets removed
  AllowDeleteObjects();

  // no instances, initially
  instanceCount = 0;

  // we start off clean
  dirty = PFalse;

  // normally save on exit (except for environment configs)
  saveOnExit = PTrue;
}

PBoolean PXConfig::AddInstance()
{
  mutex.Wait();
  PBoolean stat = instanceCount++ == 0;
  mutex.Signal();

  return stat;
}

PBoolean PXConfig::RemoveInstance(const PFilePath & /*filename*/)
{
  mutex.Wait();

  PAssert(instanceCount != 0, "PConfig instance count dec past zero");

  PBoolean stat = --instanceCount == 0;

/*
  this code required if no write thread used


  if (stat && saveOnExit && dirty) {
    WriteToFile(filename);
    dirty = PFalse;
  }
*/

  mutex.Signal();

  return stat;
}

PBoolean PXConfig::Flush(const PFilePath & filename, PBoolean force)
{
  mutex.Wait();

  PBoolean stat = instanceCount == 0;

  if ((force || (instanceCount == 0)) && saveOnExit && dirty) {
    if (instanceCount != 0) 
      PProcess::PXShowSystemWarning(2000, "Flush of config with non-zero instance");
    WriteToFile(filename);
    dirty = PFalse;
  }

  mutex.Signal();

  return stat;
}

PBoolean PXConfig::WriteToFile(const PFilePath & filename)
{
#ifdef WOT_NO_FILESYSTEM
  PProcess::PXShowSystemWarning
                       (2000, "No filing system for PXConfig::WriteToFile");
  return PTrue;
#else
  // make sure the directory that the file is to be written into exists
  PDirectory dir = filename.GetDirectory();
  if (!dir.Exists() && !dir.Create( 
                                   PFileInfo::UserExecute |
                                   PFileInfo::UserWrite |
                                   PFileInfo::UserRead)) {
    PProcess::PXShowSystemWarning(2000, "Cannot create PWLIB config dir");
    return PFalse;
  }

  PTextFile file;
  if (!file.Open(filename, PFile::WriteOnly)) {
    PProcess::PXShowSystemWarning(2001, "Cannot create PWLIB config file");
    return PFalse;
  }

  for (PINDEX i = 0; i < GetSize(); i++) {
    PXConfigSectionList & section = (*this)[i].GetList();
    file << "[" << (*this)[i] << "]" << endl;
    for (PINDEX j = 0; j < section.GetSize(); j++) {
      PXConfigValue & value = section[j];
      file << value << "=" << value.GetValue() << endl;
    }
    file << endl;
  }

  file.flush();
  file.SetLength(file.GetPosition());

  return PTrue;
#endif
}


PBoolean PXConfig::ReadFromFile (const PFilePath & filename)
{
#ifdef WOT_NO_FILESYSTEM
  PProcess::PXShowSystemWarning
                       (2000, "No filing system for PXConfig::ReadFromFile");
  return PTrue;
#else
  PINDEX len;
  PString line;

  // clear out all information
  RemoveAll();

  // attempt to open file
  PTextFile file;
  if (!file.Open(filename, PFile::ReadOnly))
    return PFalse;

  PXConfigSection * currentSection = NULL;

  // read lines in the file
  while (file.ReadLine(line)) {
    line = line.Trim();
    if ((len = line.GetLength()) > 0) {

      // ignore comments and blank lines 
      char ch = line[(PINDEX)0];
      if ((len > 0) && (ch != ';') && (ch != '#')) {
        if (ch == '[') {
          PCaselessString sectionName = (line.Mid(1,len-(line[len-1]==']'?2:1))).Trim();
          PINDEX  index;
          if ((index = GetValuesIndex(sectionName)) != P_MAX_INDEX)
            currentSection = &(*this )[index];
          else {
            currentSection = new PXConfigSection(sectionName);
            Append(currentSection);
          }
        } else if (currentSection != NULL) {
          PINDEX equals = line.Find('=');
          if (equals > 0) {
            PString keyStr = line.Left(equals).Trim();
            PString valStr = line.Right(len - equals - 1).Trim();
            PXConfigValue * value = new PXConfigValue(keyStr, valStr);
            currentSection->GetList().Append(value);
          }
        }
      }
    }
  }
  
  // close the file and return
  file.Close();
  return PTrue;
#endif
}

void PXConfig::ReadFromEnvironment (char **envp)
{
  // clear out all information
  RemoveAll();

  PXConfigSection * currentSection = new PXConfigSection("Options");
  Append(currentSection);

  while (*envp != NULL && **envp != '\0') {
    PString line(*envp);
    PINDEX equals = line.Find('=');
    if (equals > 0) {
      PXConfigValue * value = new PXConfigValue(line.Left(equals), line.Right(line.GetLength() - equals - 1));
      currentSection->GetList().Append(value);
    }
    envp++;
  }

  // can't save environment configs
  saveOnExit = PFalse;
}


static PBoolean LocateFile(const PString & baseName,
                       PFilePath & readFilename,
                       PFilePath & filename)
{
#ifndef WOT_NO_FILESYSTEM
  PFilePath userFile;

  // check the user's home directory first
  filename = readFilename = PProcess::Current().PXGetHomeDir() +
             APP_CONFIG_DIR + baseName + EXTENSION;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -