You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
497 lines
20 KiB
497 lines
20 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
Additional permissions under GNU GPL version 3 section 7 |
|
|
|
If you modify this Program, or any covered work, by linking or |
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
(or a modified version of those libraries), |
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
licensors of this Program grant you additional |
|
permission to convey the resulting work. Corresponding Source for a |
|
non-source form of such a combination shall include the source code for |
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
work. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
#ifndef plConfigInfo_h_inc |
|
#define plConfigInfo_h_inc |
|
|
|
#include "plKeysAndValues.h" |
|
#include "hsStlUtils.h" |
|
#include <stdarg.h> |
|
|
|
///////////////////////////////////////////////// |
|
|
|
typedef std::vector<std::string> plStringList; |
|
typedef std::vector<std::wstring> plWStringList; |
|
|
|
///////////////////////////////////////////////// |
|
|
|
class plConfigSource; |
|
class plConfigInfo |
|
{ |
|
public: |
|
typedef plKeysAndValues::Keys |
|
Keys; |
|
typedef plKeysAndValues::Values |
|
Values; |
|
typedef std::map<xtl::istring, plKeysAndValues> |
|
Sections; |
|
|
|
static const std::string& GlobalSection(); |
|
|
|
private: |
|
mutable Sections fSections; |
|
|
|
public: |
|
plConfigInfo(); |
|
plConfigInfo(const plConfigInfo & src); |
|
virtual ~plConfigInfo() {} |
|
plConfigInfo & operator =(const plConfigInfo & src); |
|
|
|
// REMOVE |
|
// remove all sections |
|
void Clear(); |
|
// remove section |
|
void RemoveSection(const std::string & section); |
|
// remove key from section |
|
void RemoveKey(const std::string & section, const std::string & key); |
|
// QUERY |
|
// does this section exist? |
|
bool HasSection(const std::string & section) const; |
|
// does the given section contain this key? |
|
bool HasKey(const std::string & section, const std::string & key); |
|
// does any section contain this key? |
|
bool HasKeyAny(const std::string & key); |
|
// does any of the given sections contain this key? |
|
bool HasKeyIn(const std::string & key, const char * section1, ... /*, nil*/); |
|
bool HasKeyIn(const std::string & key, const std::vector<std::string> & sections ); |
|
// does key in section have this value? |
|
bool KeyHasValue(const std::string & section, const std::string & key, const std::string & value); |
|
bool KeyHasValue(const std::string & section, const std::string & key, int value); |
|
bool KeyHasValue(const std::string & section, const std::string & key, double value); |
|
// ADD |
|
// add key=value to the section |
|
bool AddValue(const std::string & section, const std::string & key, const std::string & value, KAddValueMode mode=kAlwaysAdd); |
|
bool AddValue(const std::string & section, const std::string & key, int value, KAddValueMode mode=kAlwaysAdd); |
|
bool AddValue(const std::string & section, const std::string & key, double value, KAddValueMode mode=kAlwaysAdd); |
|
bool AddValues(const std::string & section, const std::string & key, const std::vector<std::string> & values, KAddValueMode mode=kAlwaysAdd); |
|
// GET |
|
plKeysAndValues GetSection(const std::string & section, bool & found); |
|
std::vector<std::string> GetSectionNames(); |
|
// get value for key from given section |
|
std::string GetValue(const std::string & section, const std::string & key, const std::string & defval="", bool * outFound=nil) const; |
|
int GetValue(const std::string & section, const std::string & key, int defval, bool * outFound=nil) const; |
|
double GetValue(const std::string & section, const std::string & key, double defval, bool * outFound=nil) const; |
|
std::vector<std::string> GetAllValues(const std::string & section, const std::string & key) const; |
|
// get value for key from any section |
|
std::string GetValueAny(const std::string & key, const std::string & defval="", bool * outFound=nil) const; |
|
int GetValueAny(const std::string & key, int defval, bool * outFound=nil) const; |
|
double GetValueAny(const std::string & key, double defval, bool * outFound=nil) const; |
|
std::vector<std::string> GetAllValuesAny(const std::string & key) const; |
|
// get value for key from one of the given sections |
|
std::string GetValueIn(const std::string & key, const std::string & defval, bool * outFound, const char * section1, ... /*, nil*/) const; |
|
std::string GetValueIn(const std::string & key, const std::string & defval, bool * outFound, const std::vector<std::string> & sections ) const; |
|
int GetValueIn(const std::string & key, int defval, bool * outFound, const char * section1, ... /*, nil*/) const; |
|
int GetValueIn(const std::string & key, int defval, bool * outFound, const std::vector<std::string> & sections ) const; |
|
double GetValueIn(const std::string & key, double defval, bool * outFound, const char * section1, ... /*, nil*/) const; |
|
double GetValueIn(const std::string & key, double defval, bool * outFound, const std::vector<std::string> & sections ) const; |
|
std::vector<std::string> GetAllValuesIn(const std::string & key, const char * section1, ... /*, nil*/); |
|
// ITERATORS |
|
bool GetSectionIterators(Sections::const_iterator & iter, Sections::const_iterator & end) const; |
|
bool GetKeyIterators(const xtl::istring & section, Keys::const_iterator & iter, Keys::const_iterator & end) const; |
|
bool GetValueIterators(const xtl::istring & section, const xtl::istring & key, Values::const_iterator & iter, Values::const_iterator & end) const; |
|
// CONFIG SOURCE |
|
virtual bool ReadFrom(plConfigSource * src, KAddValueMode mode=kAlwaysAdd); |
|
virtual bool WriteTo(plConfigSource * src); |
|
}; |
|
|
|
class plConfigInfoLogging |
|
{ |
|
private: |
|
plConfigInfo fConfigInfo; |
|
|
|
plConfigInfo fLog; |
|
public: |
|
plConfigInfoLogging(); |
|
~plConfigInfoLogging(); |
|
|
|
plConfigInfo* GetConfigInfo() { return &fConfigInfo; } |
|
plConfigInfo* GetConfigInfoLog() { return &fLog; } |
|
|
|
bool GetValue(std::string& retval, const std::string & section, const std::string & key, const std::string & desc, const std::string& defval = ""); |
|
bool GetValue(int& retval, const std::string & section, const std::string & key, const std::string & desc, int defval); |
|
bool GetValue(bool& retval, const std::string & section, const std::string & key, const std::string & desc, bool defval); |
|
bool GetValue(float& retval, const std::string & section, const std::string & key, const std::string & desc, float defval); |
|
bool GetValue(double& retval, const std::string & section, const std::string & key, const std::string & desc, double defval); |
|
bool GetAllValues(std::vector<std::string>& values, const std::string & section, const std::string & key, const std::string & desc); |
|
|
|
#if USE_MULT_SECTIONS |
|
// get value for key from any section |
|
bool GetValueAny(std::string& retval, const std::string & key, const std::string & desc, const std::string & defval); |
|
bool GetValueAny(int &retval, const std::string & key, const std::string & desc, int defval); |
|
bool GetValueAny(bool& retval, const std::string & key, const std::string & desc, bool defval); |
|
bool GetValueAny(float& retval, const std::string & key, const std::string & desc, float defval); |
|
bool GetValueAny(double& retval, const std::string & key, const std::string & desc, double defval); |
|
bool GetAllValuesAny(std::vector<std::string>& values, const std::string & key, const std::string & desc); |
|
|
|
// get value for key from one of the given sections |
|
bool GetValueIn(std::string& retval, const std::string & key, const std::string & desc, const std::string & defval, const char * section1, ... /*, nil*/); |
|
bool GetValueIn(std::string& retval, const std::string & key, const std::string & desc, const std::string & defval, std::vector<std::string> & sections ); |
|
bool GetValueIn(int& retval, const std::string & key, const std::string & desc, int defval, const char * section1, ... /*, nil*/); |
|
bool GetValueIn(int& retval, const std::string & key, const std::string & desc, int defval, std::vector<std::string> & sections ); |
|
bool GetValueIn(bool& retval, const std::string & key, const std::string & desc, bool defval, const char * section1, ... /*, nil*/); |
|
bool GetValueIn(bool& retval, const std::string & key, const std::string & desc, bool defval, std::vector<std::string> & sections ); |
|
bool GetValueIn(float& retval, const std::string & key, const std::string & desc, double defval, const char * section1, ... /*, nil*/); |
|
bool GetValueIn(float& retval, const std::string & key, const std::string & desc, double defval, std::vector<std::string> & sections ); |
|
bool GetValueIn(double& retval, const std::string & key, const std::string & desc, double defval, const char * section1, ... /*, nil*/); |
|
bool GetValueIn(double& retval, const std::string & key, const std::string & desc, double defval, std::vector<std::string> & sections ); |
|
#endif |
|
}; |
|
|
|
///////////////////////////////////////////////// |
|
|
|
class plConfigSource |
|
{ |
|
protected: |
|
std::string fCurrSection; // used in parsing |
|
std::string fEffectiveSection; // used in parsing |
|
KAddValueMode fAddMode; // used in parsing |
|
plConfigInfo * fConfigInfo; |
|
|
|
void SplitAt(std::string & key, std::string & value, char splitter, std::string & in); |
|
virtual bool ReadString(const std::string & in); |
|
virtual bool ReadPair(std::string & key, std::string & value); |
|
virtual bool ReadList(char ** list); |
|
virtual bool ReadSubSource( const char * name ) { return true; } |
|
|
|
protected: |
|
virtual bool ReadInto(plConfigInfo & configInfo, KAddValueMode mode=kAlwaysAdd); |
|
virtual bool WriteOutOf(plConfigInfo & configInfo); |
|
|
|
public: |
|
plConfigSource() {} |
|
virtual ~plConfigSource() {} |
|
|
|
friend class plConfigInfo; |
|
}; |
|
|
|
|
|
///////////////////////////////////////////////// |
|
|
|
class plCmdLineConfigSource : public plConfigSource |
|
{ |
|
int fArgc; |
|
char ** fArgv; |
|
std::string fMySection; |
|
protected: |
|
bool ReadInto(plConfigInfo & configInfo, KAddValueMode mode=kAlwaysAdd); |
|
public: |
|
plCmdLineConfigSource(int argc, char ** argv, const char * mySection="CmdLine"); |
|
}; |
|
|
|
|
|
///////////////////////////////////////////////// |
|
|
|
class plEnvConfigSource : public plConfigSource |
|
{ |
|
char ** fEnvp; |
|
std::string fMySection; |
|
protected: |
|
bool ReadInto(plConfigInfo & configInfo, KAddValueMode mode=kAlwaysAdd); |
|
public: |
|
plEnvConfigSource(char ** envp, const char * mySection="Environment"); |
|
}; |
|
|
|
|
|
///////////////////////////////////////////////// |
|
|
|
class plIniConfigSource : public plConfigSource |
|
{ |
|
protected: |
|
std::string fFileName; |
|
bool ReadInto(plConfigInfo & configInfo, KAddValueMode mode=kAlwaysAdd); |
|
bool WriteOutOf(plConfigInfo & configInfo); |
|
public: |
|
plIniConfigSource(const char * iniFileName); |
|
}; |
|
|
|
///////////////////////////////////////////////// |
|
// just like above, but works with hsStream-derived classes |
|
|
|
class hsStream; |
|
class plIniStreamConfigSource : public plConfigSource |
|
{ |
|
protected: |
|
hsStream * fStream; |
|
bool ReadInto(plConfigInfo & configInfo, KAddValueMode mode=kAlwaysAdd); |
|
bool WriteOutOf(plConfigInfo & configInfo); |
|
public: |
|
plIniStreamConfigSource(hsStream * stream); |
|
}; |
|
|
|
///////////////////////////////////////////////// |
|
|
|
// an ini file reader/writer that ignores section headers and puts all |
|
// data in an unnamed section, or more accurately, in a section named "". |
|
class plIniNoSectionsConfigSource : public plConfigSource |
|
{ |
|
std::string fFileName; |
|
protected: |
|
bool ReadString(const std::string & in); |
|
bool ReadInto(plConfigInfo & configInfo, KAddValueMode mode=kAlwaysAdd); |
|
bool WriteOutOf(plConfigInfo & configInfo); |
|
public: |
|
plIniNoSectionsConfigSource(const char * iniFileName); |
|
}; |
|
|
|
///////////////////////////////////////////////// |
|
|
|
// an ini file reader that only reads specified sections |
|
class plIniSectionConfigSource : public plIniConfigSource |
|
{ |
|
typedef std::vector<xtl::istring> |
|
Sections; |
|
protected: |
|
Sections fSections; |
|
bool ReadPair(std::string & key, std::string & value); |
|
bool ReadSubSource( const char * name ); |
|
public: |
|
plIniSectionConfigSource(const char * iniFileName, std::vector<std::string> & sections); |
|
}; |
|
|
|
///////////////////////////////////////////////// |
|
|
|
// TODO: This would be a cool thing. not needed right now though. |
|
class plDatabaseConfigSource : public plConfigSource |
|
{ |
|
protected: |
|
bool ReadInto(plConfigInfo & configInfo, KAddValueMode mode=kAlwaysAdd); |
|
bool WriteOutOf(plConfigInfo & configInfo); |
|
public: |
|
plDatabaseConfigSource(const char * connectString); |
|
}; |
|
|
|
|
|
///////////////////////////////////////////////// |
|
|
|
class plDebugConfigSource : public plConfigSource |
|
{ |
|
protected: |
|
std::string fFileName; |
|
bool WriteOutOf(plConfigInfo & configInfo); |
|
public: |
|
plDebugConfigSource(){} |
|
}; |
|
|
|
///////////////////////////////////////////////// |
|
|
|
class plWWWAuthenticateConfigSource : public plConfigSource |
|
{ |
|
const std::string& fAuth; |
|
protected: |
|
bool ReadInto(plConfigInfo & configInfo, KAddValueMode mode=kAlwaysAdd); |
|
public: |
|
plWWWAuthenticateConfigSource(const std::string& auth); |
|
}; |
|
|
|
//////////////////////////////////////////////////////////////////// |
|
|
|
// NOTE: plClass _must_ appear first in a multiple-inheritance list. |
|
class plClass |
|
{ |
|
public: |
|
virtual void Unused(){} |
|
}; |
|
|
|
//////////////////////////////////////////////////////////////////// |
|
|
|
typedef bool (plClass::*TEvaluate)(); |
|
typedef bool (plClass::*TEvaluateConst)() const; |
|
struct plEvaluate |
|
{ |
|
plClass * fTarget; |
|
bool (plClass::*fEvaluate)(); |
|
bool (plClass::*fEvaluateConst)() const; |
|
plEvaluate( plClass * target=nil, TEvaluate evaluate=nil ) |
|
: fTarget(target) |
|
, fEvaluate(evaluate) |
|
, fEvaluateConst(nil) |
|
{} |
|
plEvaluate( plClass * target, TEvaluateConst evaluate ) |
|
: fTarget(target) |
|
, fEvaluateConst(evaluate) |
|
, fEvaluate(nil) |
|
{} |
|
bool operator()() |
|
{ |
|
if (fEvaluate) |
|
return (fTarget)?(fTarget->*fEvaluate)():true; |
|
else |
|
if (fEvaluateConst) |
|
return (fTarget)?(fTarget->*fEvaluateConst)():true; |
|
else |
|
return true; |
|
} |
|
}; |
|
|
|
//////////////////////////////////////////////////////////////////// |
|
|
|
typedef std::string (plClass::*TModify)(const std::string & value); |
|
|
|
struct plModify |
|
{ |
|
plClass * fTarget; |
|
std::string (plClass::*fModify)(const std::string & value); |
|
plModify( plClass * target=nil, TModify modify=nil ) |
|
: fTarget(target) |
|
, fModify(modify) |
|
{} |
|
std::string operator()(const std::string & value) { return (fTarget)?(fTarget->*fModify)(value):value;} |
|
std::string operator()(const std::string & value) const { return (fTarget)?(fTarget->*fModify)(value):value;} |
|
}; |
|
|
|
//////////////////////////////////////////////////////////////////// |
|
|
|
class plConfigValueBase |
|
{ |
|
public: |
|
std::string fConfigName; |
|
std::string fConfigGroup; |
|
plEvaluate fReadEvaluate; // returns true if we want to read this value from options |
|
plEvaluate fWriteEvaluate; // returns true if we want to write this value to options |
|
plModify fReadModify; // may modify the value being read from options |
|
plModify fWriteModify; // may modify the value being written to options |
|
plModify fGetModify; // may modify the value when being assigned |
|
plModify fSetModify; // may modify the value when being accessed |
|
plConfigValueBase( const char * configName="", const char * configGroup="" ) |
|
: fConfigName(configName) |
|
, fConfigGroup(configGroup) |
|
{} |
|
void SetConfigName(const char * name) { fConfigName=(name)?name:"";} |
|
std::string GetConfigName() const { return fConfigName;} |
|
void SetConfigGroup(const char * group) { fConfigGroup=group;} |
|
std::string GetConfigGroup() const { return fConfigGroup;} |
|
bool HasConfigName() { return fConfigName.length()>0;} |
|
bool HasConfigGroup() { return fConfigGroup.length()>0;} |
|
virtual void ConfigRead(plConfigInfo * opts); |
|
virtual void ConfigWrite(plConfigInfo * opts); |
|
void SetValue(const char * value); |
|
std::string GetValue() const; |
|
virtual void ISetValue(const char * value) = 0; |
|
virtual std::string IGetValue() const = 0; |
|
|
|
void SetReadEvaluate(plClass * targetObj, TEvaluate evalFunc); |
|
void SetWriteEvaluate(plClass * targetObj, TEvaluate evalFunc); |
|
void SetWriteEvaluate(plClass * targetObj, TEvaluateConst evalFunc); |
|
void SetReadModify(plClass * targetObj, TModify modifyFunc); |
|
void SetWriteModify(plClass * targetObj, TModify modifyFunc); |
|
void SetGetModify(plClass * targetObj, TModify modifyFunc); |
|
void SetSetModify(plClass * targetObj, TModify modifyFunc); |
|
}; |
|
|
|
//////////////////////////////////////////////////////////////////// |
|
|
|
class plConfigValue : public plConfigValueBase |
|
{ |
|
public: |
|
plConfigValue( const char * configName="", const char * configGroup="" ) |
|
: plConfigValueBase(configName, configGroup) |
|
{} |
|
std::string fConfigValue; |
|
void ISetValue(const char * value) { fConfigValue=value;} |
|
std::string IGetValue() const { return fConfigValue;} |
|
}; |
|
|
|
//////////////////////////////////////////////////////////////////// |
|
|
|
class plConfigAggregateValue : public plConfigValueBase |
|
{ |
|
public: |
|
std::vector<plConfigValueBase*> fItems; |
|
plConfigAggregateValue( |
|
const char * name=nil, |
|
// A vararg here would not work because of a |
|
// multiple inheritance issue. Classes that are |
|
// plConfigValueBase are likely to be derived from |
|
// plClass also. Since plClass must be first in |
|
// the inheritance list, the vararg would not |
|
// point to the plConfigValueBase vtable that we |
|
// need to access. |
|
plConfigValueBase * item1=nil, |
|
plConfigValueBase * item2=nil, |
|
plConfigValueBase * item3=nil, |
|
plConfigValueBase * item4=nil, |
|
plConfigValueBase * item5=nil, |
|
plConfigValueBase * item6=nil, |
|
plConfigValueBase * item7=nil); |
|
void ISetValue(const char * value); |
|
std::string IGetValue() const; |
|
void AddItem(plConfigValueBase * item); |
|
void AddItems( |
|
plConfigValueBase * item1=nil, |
|
plConfigValueBase * item2=nil, |
|
plConfigValueBase * item3=nil, |
|
plConfigValueBase * item4=nil, |
|
plConfigValueBase * item5=nil, |
|
plConfigValueBase * item6=nil, |
|
plConfigValueBase * item7=nil); |
|
}; |
|
|
|
//////////////////////////////////////////////////////////////////// |
|
|
|
class plConfigValueProxy : public plConfigValueBase |
|
{ |
|
plConfigValueBase * fConfigurable; |
|
public: |
|
plConfigValueProxy(plConfigValueBase * item=nil) |
|
: fConfigurable(item) |
|
{} |
|
void Set(plConfigValueBase * item) { fConfigurable=item;} |
|
void ISetValue(const char * value) { fConfigurable->ISetValue(value);} |
|
std::string IGetValue() const { return fConfigurable->IGetValue();} |
|
}; |
|
|
|
//////////////////////////////////////////////////////////////////// |
|
|
|
class plConfigGroup |
|
{ |
|
public: |
|
plConfigInfo fOpts; |
|
std::string fGroupName; |
|
std::vector<plConfigValueBase*> fItems; |
|
plConfigGroup(const char * groupName=""); |
|
bool Read(plConfigSource * src); |
|
bool Write(plConfigSource * src); |
|
void AddItem(plConfigValueBase * item, const char * name=nil); |
|
}; |
|
|
|
//////////////////////////////////////////////////////////////////// |
|
|
|
#endif // plConfigInfo_h_inc
|
|
|