From: Marc D. <bdu...@gm...> - 2004-12-24 09:28:16
|
Excellent! Prefs is an API for loading saving/loading application preferences as well as for all sorts of config files. The important thing is that it doesnt build on simple string maps but on concrete Entry and Section types. So when you change someting in the Prefs and forget to change it in your program you are more likely to realise it at compile time. Preference data is organised in sections. Each section has a list of subsections and a list of entries yielding a tree like structure. class Section { /* ... */ private: std::list<Entriy*> _entries; std::list<Section*> _sections }; Entries and Sections have a name and a parent. The both derive from Node: class Node { /* ... */ private: Node* _parentNode; std::string _name; }; Entry and Section are base classes and you CAN add derived ones or use one of the simple predefined Entry types (String, int, float etc...) made available by the ValueEntry template class for all streamables. class Entry : public Node { public: Entry(const std::string& name); virtual std::string str() const = 0; }; template <class ValueT> class ValueEntry : public Entry { public: ValueEntry(const std::string& name, const ValueT& value); virtual std::string str() const; // stream conversion of _value; const ValueT& value() const; void setValue(const ValueT& value); private: ValueT _value; }; // examples typedef ValueEntry<std::string> StringEntry; typedef ValueEntry<int> IntEntry; The Prefs class holds the root section and a PrefsStore class which knows how to load and save the data. This would be where I have to look at s11n. class PrefsStore { public: PrefsStore() {} virtual ~PrefsStore() {} virtual void load(Prefs::Section& root) throw(P::IOError) = 0; virtual void update(Prefs::Section& root) throw(P::IOError) = 0; }; class Prefs { /* ... */ private: Section _root; PrefsStore* _store; }; We want to be able to use Prefs with predefined strores like INI, xml or even some network location. @Stephan what would you suggest? wrapping up s11n in IniStore, XmlStore etc? Or kick out PrefsStore and use s11n? It would also be interesting to have the parsers as seperate classes in P2. One other idea I had was to have Iterators that stride (hope that is the correct term) over one type of entry. So if you want to have only the nameserver entries from a resolv.conf file you would do something like this: - Impelment ResolvConf derived from Prefs with its store class for the resolv.conf config file format with a NameserverEntry class derived from i.e. StringEntry - Use "stride" iterator for NameserverEntries to print all nameserver entries. Now for a simple file like resolv.conf it doesnt look like much, but imagine to simply iterate through all InputDevice sections in a XF86Config. The "stride" or "select" iterator was rather easy to implement as a template class encapsulating a normal "linear" iterator. operator++ has to do some type checking though. But maybe that should not be part of Prefs but part of the the containers, with SelectTraits or something. happy cristmas, Marc On Friday 24 Dec 2004 00:43, stephan beal wrote: > On Thursday 23 December 2004 22:52, Marc Duerner wrote: > > Hello, > > I still want to look at P::Prefs and some containers. Specially the > > first one may benefit from s11n. > > Any std container is usably out of the box by s11n: > > #include <s11n.net/s11n/s11nlite.hpp> > #include <s11n.net/s11n/list.hpp> > #include <s11n.net/s11n/map.hpp> > #include <s11n.net/s11n/pods_streamable.hpp> > > ... > > typedef map<string,list<map<int,string> > > Geez; > > Geez g; > ... populate it ... > bool worked = s11nlite::save( g, stream|file ); > > Loading has 2 options: > > #1: > Geez * g = s11nlite::load_serializable<Geez>( stream|file ); > > #2: > s11nlite::node_type * n = s11nlite::load_node( stream|file ); > if( ! n ) { ... error ... } > Geez g; > bool worked= = s11nlite::deserialize( *n, g ); > > > P::s11n works identically, but also supports URLs (whatever is supported > by IOManager). |