00001
00014 #ifndef __IniFile_h__
00015 #define __IniFile_h__
00016
00017 #include <string>
00018 #include <map>
00019 #include <list>
00020 #include <vector>
00021
00022 #include <YCP.h>
00023
00024 using std::map;
00025 using std::multimap;
00026 using std::list;
00027 using std::vector;
00028 using std::string;
00029
00036 class IniBase
00037 {
00038 protected:
00040 string name;
00042 string comment;
00044 int read_by;
00046 bool dirty;
00047
00049 IniBase (int rb)
00050 : name (), comment (), read_by (rb), dirty (false) {}
00052 IniBase (const string &n)
00053 : name (n), comment (), read_by (0), dirty (true) {}
00054 public:
00055 virtual ~IniBase () {}
00056
00057 const char* getName() const { return name.c_str(); }
00058 const char* getComment() const { return comment.c_str(); }
00059 int getReadBy() const { return read_by; }
00060
00062 virtual void clean() { dirty = false; }
00063
00065 void setName(const string&c) { dirty = true; name = c; }
00067 void setComment(const string&c) { dirty = true; comment = c; }
00069 void setReadBy(int r) { dirty = true; read_by = r; }
00071 void setDirty() { dirty = true; }
00072
00074 void initName(const string&c) { if (!dirty) name = c; }
00076 void initComment(const string&c) { if (!dirty) comment = c; }
00078 void initReadBy(const int r) { if (!dirty) read_by = r; }
00079
00081 void init(const string &n,const string&c, int rb)
00082 {
00083 if (!dirty)
00084 {
00085 name = n;
00086 comment = c;
00087 read_by = rb;
00088 }
00089 }
00090
00091 protected:
00095 virtual YCPMap getAllDoIt () {
00096 YCPMap m;
00097
00098 m->add (YCPString ("name"), YCPString (name));
00099 m->add (YCPString ("type"), YCPInteger (read_by));
00100 m->add (YCPString ("comment"), YCPString (comment));
00101 return m;
00102 }
00103
00105 bool getMapString (const YCPMap &in, const string &k, string &s) {
00106 YCPValue v = in->value (YCPString (k));
00107 if (v.isNull () || !v->isString ())
00108 {
00109 y2error ("Missing in Write (.all): %s", k.c_str ());
00110 return false;
00111 }
00112 s = v->asString ()->value ();
00113 return true;
00114 }
00115
00117 bool getMapInteger (const YCPMap &in, const string &k, int &i) {
00118 YCPValue v = in->value (YCPString (k));
00119 if (v.isNull () || !v->isInteger ())
00120 {
00121 y2error ("Missing in Write (.all): %s", k.c_str ());
00122 return false;
00123 }
00124 i = v->asInteger ()->value ();
00125 return true;
00126 }
00127
00128 virtual int setAllDoIt (const YCPMap &in) {
00129 dirty = true;
00130
00131 bool ok = true;
00132 ok = ok && getMapString (in, "name", name);
00133 ok = ok && getMapInteger (in, "type", read_by);
00134 ok = ok && getMapString (in, "comment", comment);
00135 return ok? 0: -1;
00136 }
00137 };
00138
00142 class IniEntry : public IniBase
00143 {
00144 private:
00146 string val;
00147 public:
00148 IniEntry ()
00149 : IniBase (0), val () {}
00151 IniEntry (const char *u): IniBase (u) {}
00152
00153 const char* getValue() const { return val.c_str(); }
00154
00155 void setValue(const string&c) { dirty = true; val = c; }
00156
00158 void initValue(const string&c) { if (!dirty) val = c; }
00160 void initReadBy(const int r) { if (!dirty) read_by = r; }
00161
00163 void init(const string &n, const string &c, int rb, const string &v)
00164 {
00165 if (!dirty)
00166 {
00167 val = v;
00168 IniBase::init (n, c, rb);
00169 }
00170 }
00171
00172 YCPMap getAllDoIt () {
00173 YCPMap m = IniBase::getAllDoIt ();
00174 m->add (YCPString ("kind"), YCPString ("value"));
00175 m->add (YCPString ("value"), YCPString (val));
00176 return m;
00177 }
00178
00179 int setAllDoIt (const YCPMap &in) {
00180 int ret = IniBase::setAllDoIt (in);
00181 if (ret == 0)
00182 {
00183 string kind;
00184 if (!getMapString (in, "kind", kind) || kind != "value")
00185 {
00186 y2error ("Kind should be 'value'");
00187 return -1;
00188 }
00189
00190 if (!getMapString (in, "value", val))
00191 {
00192 return -1;
00193 }
00194 }
00195 return ret;
00196 }
00197 };
00198
00199 class IniSection;
00200
00201
00202 enum IniType { VALUE, SECTION,};
00203 struct IniContainerElement;
00204
00205 typedef list<IniContainerElement> IniContainer;
00206 typedef IniContainer::iterator IniIterator;
00207
00209 typedef multimap<string, IniIterator> IniEntryIndex;
00210 typedef multimap<string, IniIterator> IniSectionIndex;
00219 typedef IniEntryIndex::iterator IniEntryIdxIterator;
00220 typedef IniSectionIndex::iterator IniSectionIdxIterator;
00221
00222 class IniParser;
00223
00227 class IniSection : public IniBase
00228 {
00229 private:
00230
00231
00232
00234 const IniParser *ip;
00235
00240 string end_comment;
00241
00246 int rewrite_by;
00247
00253 IniContainer container;
00254
00258 IniEntryIndex ivalues;
00262 IniSectionIndex isections;
00263
00265 void reindex ();
00266
00277 int getMyValue (const YCPPath &p, YCPValue &out, int what, int depth);
00288 int getValue (const YCPPath&p, YCPValue&out,int what, int depth = 0);
00299 int getSectionProp (const YCPPath&p, YCPValue&out,int what, int depth = 0);
00309 int getAll (const YCPPath&p, YCPValue&out, int depth);
00313 YCPMap getAllDoIt ();
00314
00321 int myDir (YCPList& l, IniType what);
00322
00332 int dirHelper (const YCPPath&p, YCPList&out,int sections,int depth = 0);
00343 int setMyValue (const YCPPath &p, const YCPValue&in, int what, int depth);
00352 int setValue (const YCPPath&p,const YCPValue&in,int what, int depth = 0);
00361 int setSectionProp (const YCPPath&p,const YCPValue&in, int what, int depth);
00370 int setAll (const YCPPath&p, const YCPValue& in, int depth);
00376 int setAllDoIt (const YCPMap &in);
00383 int delValue (const YCPPath&p, int depth);
00390 int delSection (const YCPPath&p, int depth);
00391
00396 void delMyValue (const string &k);
00400 void delValue1 (IniEntryIdxIterator exi);
00404 void delSection1 (IniSectionIdxIterator sxi);
00405
00412 int getValueFlat (const YCPPath&p, YCPValue&out);
00419 int setValueFlat (const YCPPath&p, const YCPValue& in);
00423 int delValueFlat (const YCPPath&p);
00427 int dirValueFlat (const YCPPath&p, YCPList&l);
00428
00429 public:
00431 IniSection (const char *u): IniBase (u) {}
00432
00433 IniSection (const IniParser *p)
00434 : IniBase (-1),
00435 ip (p),
00436 end_comment (), rewrite_by(-1),
00437 container (), ivalues (), isections ()
00438 {}
00439
00444 IniSection (const IniSection &s) :
00445 IniBase (s),
00446 ip (s.ip),
00447 end_comment (s.end_comment), rewrite_by (s.rewrite_by),
00448 container (s.container)
00449 { reindex (); }
00450
00451 void operator = (const IniSection &s)
00452 {
00453 if (&s == this)
00454 {
00455 return;
00456 }
00457 IniBase::operator = (s);
00458 ip = s.ip;
00459 end_comment = s.end_comment; rewrite_by = s.rewrite_by;
00460 container = s.container;
00461
00462 reindex ();
00463 }
00464
00465 virtual ~IniSection () {}
00466
00472 IniSection (const IniParser *p, string n)
00473 : IniBase (n),
00474 ip (p),
00475 end_comment (), rewrite_by(0),
00476 container(), ivalues (), isections ()
00477 {}
00486 void initValue (const string&key,const string&val,const string&comment,int rb);
00495 void initSection (const string&name,const string&comment,int rb, int wb=-2);
00500 void initReadBy () { read_by = -1; }
00501
00503 void setRewriteBy (int c) { dirty = true; rewrite_by = c; }
00504 int getRewriteBy() { return rewrite_by; }
00509 int getSubSectionRewriteBy (const char*name);
00510
00517 void setEndComment (const char*c);
00518 const char* getEndComment() const { return end_comment.c_str(); }
00519
00520 bool isDirty ();
00522 virtual void clean();
00523
00532 IniSection& findSection(const vector<string>&path, int from = 0);
00546 int findEndFromUp(const vector<string>&path, int wanted, int found = -1, int from = 0);
00547
00551 void Dump ();
00552
00557 int Read (const YCPPath&p, YCPValue&out, bool rewrite);
00561 int Dir (const YCPPath&p, YCPList&out);
00566 int Write (const YCPPath&p, const YCPValue&v, bool rewrite);
00572 int Delete (const YCPPath&p);
00573
00574
00575 IniIterator getContainerBegin ();
00576 IniIterator getContainerEnd ();
00577
00583
00584
00591 IniSection& getSection (const char*name);
00592 };
00593
00597 class IniContainerElement
00598 {
00599 IniType _t;
00600 IniEntry _e;
00601 IniSection _s;
00602
00603 public:
00605 IniType t () const { return _t; }
00606 const IniEntry& e () const { return _e; }
00607 IniEntry& e () { return _e; }
00608 const IniSection& s () const { return _s; }
00609 IniSection& s () { return _s; }
00610
00612 IniContainerElement (const IniEntry& e) :
00613 _t (VALUE),
00614 _e (e),
00615
00616 _s (IniSection ((const IniParser *)NULL))
00617 {}
00618
00620 IniContainerElement (const IniSection& s) :
00621 _t (SECTION),
00622
00623 _e (IniEntry ()),
00624 _s (s)
00625 {}
00626
00627 IniContainerElement (const IniContainerElement& c) :
00628 _t (c._t),
00629 _e (c._e),
00630 _s (c._s)
00631 {}
00632 };
00633
00634
00635 #endif//__IniFile_h__