123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- #include <precomp.h>
- #include "config.h"
- #include <bfc/pair.h>
- #include <bfc/ptrlist.h>
- #include <bfc/parse/pathparse.h>
- #include <api/xml/xmlwrite.h>
- #include "../xml/ifc_xmlreadercallbackI.h"
- #include "../xml/obj_xml.h"
- #include <bfc/string/url.h>
- #include <api/service/waservicefactory.h>
- static StringW iniFile;
- #define XNFNAME L"studio.xnf"
- class StringPairCompare
- {
- public:
- static int compareItem(StringPair *p1, StringPair *p2)
- {
- int r = wcscmp(p1->a.getValue(), p2->a.getValue());
- if (r == 0)
- return CMP3(p1, p2);
- else
- return r;
- }
- static int compareAttrib(const wchar_t *attrib, StringPair *item)
- {
- return wcscmp(attrib, item->a.getValue());
- }
- };
- static PtrListQuickSorted<StringPair, StringPairCompare> strings;
- class Reader : public ifc_xmlreadercallbackI
- {
- public:
- ~Reader();
- void xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
- void xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag);
- void readem();
- private:
- PtrList<StringW> sections;
- };
- Reader::~Reader()
- {
- sections.deleteAll();
- }
- void Reader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
- {
- if (!WCSICMP(xmltag, L"section"))
- {
- const wchar_t *name = params->getItemValue(L"name");
- if (name == NULL)
- return ;
- StringW *strName = new StringW(name);
- Url::decode(*strName);
- sections.addItem(strName);
- }
- else if (!WCSICMP(xmltag, L"entry"))
- {
- const wchar_t *name = params->getItemValue(L"name");
- const wchar_t *value = params->getItemValue(L"value");
- // just in case
- if (!WCSICMP(name, L"(null)")) name = NULL;
- if (!WCSICMP(value, L"(null)")) value = NULL;
- if (name == NULL /*| !*name */ || value == NULL /*|| !*value*/) return ;
- StringW strName = name;
- Url::decode(strName);
- StringW strValue = value;
- Url::decode(strValue);
- StringW n;
- for (int i = 0; i < sections.getNumItems(); i++)
- {
- n.catPostSeparator(*sections[i], '/');
- }
- n += strName;
-
- StringPair *p = new StringPair(n, strValue);
- strings.addItem(p);
- }
- }
- void Reader::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag)
- {
- if (!WCSICMP(xmltag, L"section"))
- {
- StringW *last = sections.getLast();
- sections.removeLastItem();
- delete last;
- }
- }
- void LoadXmlFile(obj_xml *parser, const wchar_t *filename);
- void Reader::readem()
- {
- strings.deleteAll();
-
- if (iniFile.isempty())
- {
- iniFile = StringPathCombine(WASABI_API_APP->path_getUserSettingsPath(), XNFNAME);
- }
- waServiceFactory *parserFactory = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
- if (parserFactory)
- {
- obj_xml *parser = (obj_xml *)parserFactory->getInterface();
- if (parser)
- {
- parser->xmlreader_registerCallback(L"WinampXML\fconfiguration\f*", this);
- parser->xmlreader_registerCallback(L"WasabiXML\fconfiguration\f*", this);
- parser->xmlreader_open();
- LoadXmlFile(parser, iniFile);
- parser->xmlreader_unregisterCallback(this);
- parser->xmlreader_close();
- parserFactory->releaseInterface(parser);
- parser = 0;
- }
- }
- }
- StringPair *ConfigFile::getPair(const wchar_t *name)
- {
- ASSERT(!sectionname.isempty());
- StringW nname;
- nname.catPostSeparator(sectionname.getValue(), '/');
- nname.cat(name);
- return strings.findItem(nname.getValue()); // cast to make PtrListSorted happy
- }
- StringPair *ConfigFile::makePair(const wchar_t *name, const wchar_t *value)
- {
- StringPair *ret = getPair(name);
- if (ret == NULL)
- {
- StringW nname;
- nname.catPostSeparator(sectionname.getValue(), '/');
- nname.cat(name);
- ret = new StringPair(nname, value);
- strings.addItem(ret);
- }
- else
- {
- ret->b.setValue(value);
- }
- return ret;
- }
- static int ninstances, inited;
- ConfigFile::ConfigFile(const wchar_t *section, const wchar_t *name)
- {
- sectionname = section;
- prettyname = name;
- ninstances++;
- }
- void ConfigFile::initialize()
- {
- Reader().readem();
- }
- ConfigFile::~ConfigFile()
- {
- ninstances--;
- if (ninstances == 0)
- {
- FILE *fp = _wfopen(iniFile, WF_WRITE_TEXT);
- if (fp != NULL)
- {
- // write out the file
- XMLWrite xml(fp, L"WasabiXML");
- const wchar_t *app = WASABI_API_APP->main_getVersionString();
- if (!app)
- app = L"thousands of irascible butt monkeys";
- xml.comment(StringPrintfW(L"Generated by: %s (%d)", app, WASABI_API_APP->main_getBuildNumber()));
- xml.pushCategory(L"configuration");
- PtrList<StringW> cats;
- for (int i = 0; i < strings.getNumItems(); i++)
- {
- StringPair *p = strings[i];
- PathParserW pp(p->a);
- int climit = MIN(pp.getNumStrings() - 1, cats.getNumItems());
- int j;
- for (j = 0; j < climit; j++)
- {
- if (WCSICMP(*cats[j], pp.enumString(j)))
- {
- climit = j;
- break;
- }
- }
- while (cats.getNumItems() > climit)
- {
- StringW *s = cats.getLast();
- xml.popCategory();
- cats.removeLastItem();
- delete s;
- }
- for (j = climit; j < pp.getNumStrings() - 1; j++)
- {
- StringW *s = cats.addItem(new StringW(pp.enumString(j)));
- xml.pushCategoryAttrib(L"section");
- StringW enc = *s;
- Url::encode(enc, FALSE, URLENCODE_EXCLUDE_ABOVEEQ32);
- xml.writeCategoryAttrib(L"name", enc);
- xml.closeCategoryAttrib();
- }
- xml.pushCategoryAttrib(L"entry", TRUE);
- StringW enc = pp.getLastString();
- Url::encode(enc, FALSE, URLENCODE_EXCLUDE_ABOVEEQ32);
- xml.writeCategoryAttrib(L"name", enc);
- enc = p->b;
- Url::encode(enc, FALSE, URLENCODE_EXCLUDE_ABOVEEQ32);
- if (enc.iscaseequal(L"(null)") || enc.getValue() == NULL)
- enc.setValue(L"");
- xml.writeCategoryAttrib(L"value", enc);
- xml.closeCategoryAttrib();
- xml.popCategory();
- }
- while (xml.popCategory()) ;
- strings.deleteAll();
- fclose(fp);
- } // fp != NULL
- } // ninstances==0
- }
- int verifyName(const wchar_t *str)
- {
- for (const wchar_t *p = str; *p; p++)
- {
- if (!ISALPHA(*p) &&
- !ISDIGIT(*p) &&
- !ISPUNCT(*p) &&
- !ISSPACE(*p) &&
- *p != '|' && *p != '_')
- return 0;
- }
- return 1;
- }
- void ConfigFile::setInt(const wchar_t *name, int val)
- {
- INCRITICALSECTION(cs);
- if (name == NULL) return ;
- if (!verifyName(name))
- {
- DebugStringW(L"illegal name given\n");
- //__asm { int 3 };
- return ;
- }
- makePair(name, StringPrintfW(val));
- }
- int ConfigFile::getInt(const wchar_t *name, int def_val)
- {
- INCRITICALSECTION(cs);
- if (name == NULL) return def_val;
- StringPair *p = getPair(name);
- if (p == NULL) return def_val;
- return WTOI(p->b.getValue());
- }
- void ConfigFile::setString(const wchar_t *name, const wchar_t *str)
- {
- INCRITICALSECTION(cs);
- if (name == NULL) return ;
- if (!verifyName(name))
- {
- DebugStringW(L"illegal name given\n");
- return ;
- }
- if (str == NULL)
- {
- StringPair *p = getPair(name);
- if (p != NULL)
- {
- strings.delItem(p);
- delete p;
- return ;
- }
- }
- makePair(name, str);
- }
- int ConfigFile::getString(const wchar_t *name, wchar_t *buf, int buf_len, const wchar_t *def_str)
- {
- INCRITICALSECTION(cs);
- if (name == NULL || buf == NULL) return -1;
- if (def_str == NULL)
- def_str = L"";
- StringPair *p = getPair(name);
- if (p == NULL)
- WCSCPYN(buf, def_str, buf_len);
- else
- WCSCPYN(buf, p->b.getValueSafe(), buf_len);
- return 1;
- }
- int ConfigFile::getStringLen(const wchar_t *name)
- {
- INCRITICALSECTION(cs);
- if (name == NULL) return -1;
- StringPair *p = getPair(name);
- if (p == NULL) return -1;
- return wcslen(p->b.getValue());
- }
|