implemented value probing in SkvEnv

This commit is contained in:
hyung-hwan 2018-07-14 17:05:08 +00:00
parent 7a02450a5d
commit b510d11c55
15 changed files with 113 additions and 25 deletions

View File

@ -50,16 +50,16 @@ public:
{
qse_char_t sctn[MAX_SCTN_LEN + 1];
qse_char_t key [MAX_KEY_LEN + 1];
qse_char_t name[MAX_NAME_LEN + 1];
qse_char_t name[MAX_NAME_LEN + 1]; // sctn*key
qse_char_t dval[MAX_DVAL_LEN + 1]; // default value
ProbeProc probe;
};
typedef QSE::LinkedList<Item> ItemList;
SkvEnv (Mmgr* mmgr = QSE_NULL);
~SkvEnv ();
virtual ~SkvEnv ();
int addItem (const qse_char_t* name, const qse_char_t* dval, ProbeProc probe);
int addItem (const qse_char_t* name, const qse_char_t* dval, ProbeProc probe = QSE_NULL);
int removeItem (const qse_char_t* name);
const qse_char_t* getValue (const qse_char_t* name) const;
@ -74,6 +74,18 @@ protected:
int split_name (const qse_char_t* name, qse_char_t** sctn, qse_size_t* sctn_len, qse_char_t** key, qse_size_t* key_len);
int set_value_with_item (Item& item, const qse_char_t* value);
virtual int probe_item_value (const Item& item, const qse_char_t* value)
{
if (item.probe && (this->*item.probe)(value) <= -1) return -1;
return 0;
}
int call_probe_item_value (const Item& item, const qse_char_t* value)
{
try { return this->probe_item_value(item, value); }
catch (...) { return -1; }
}
};
QSE_END_NAMESPACE(QSE)

View File

@ -5,7 +5,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/include
lib_LTLIBRARIES = libqsexli.la
libqsexli_la_SOURCES = xli.h xli.c err.c \
libqsexli_la_SOURCES = xli-prv.h xli.c err.c \
read.c read-ini.c read-json.c \
write.c write-ini.c write-json.c \
std.c

View File

@ -402,7 +402,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/include
lib_LTLIBRARIES = libqsexli.la $(am__append_1)
libqsexli_la_SOURCES = xli.h xli.c err.c \
libqsexli_la_SOURCES = xli-prv.h xli.c err.c \
read.c read-ini.c read-json.c \
write.c write-ini.c write-json.c \
std.c

View File

@ -28,8 +28,10 @@
#include <qse/xli/SkvEnv.hpp>
#include <qse/xli/stdxli.h>
#include <qse/cmn/str.h>
#include "../cmn/mem-prv.h"
#include "xli-prv.h"
#define SCTN_KEY_SPLITTER QSE_T('*')
@ -90,7 +92,7 @@ int SkvEnv::removeItem (const qse_char_t* name)
if (this->split_name (name, &sctn, &sctn_len, &key, &key_len) == -1) return -1;
for (ItemList::Node* np = item_list.getHeadNode(); np; np = np->getNextNode())
for (ItemList::Node* np = this->item_list.getHeadNode(); np; np = np->getNextNode())
{
Item& item = np->value;
if (qse_strxcmp(sctn, sctn_len, item.sctn) == 0 &&
@ -113,7 +115,7 @@ const qse_char_t* SkvEnv::getValue (const qse_char_t* name) const
QSE_ASSERT (pair->val != QSE_NULL);
QSE_ASSERT (pair->val->type == QSE_XLI_STR);
return (((qse_xli_str_t*)pair->val))->ptr;
}
@ -172,7 +174,8 @@ int SkvEnv::split_name (const qse_char_t* name, qse_char_t** sctn, qse_size_t* s
int SkvEnv::set_value_with_item (Item& item, const qse_char_t* value)
{
if (item.probe && (this->*item.probe)(value) <= -1) return -1;
#if 0
if (this->probe_item_value(item, value) <= -1) return -1;
qse_cstr_t v = { (qse_char_t*)value, qse_strlen(value) };
@ -195,7 +198,70 @@ int SkvEnv::set_value_with_item (Item& item, const qse_char_t* value)
if (!qse_xli_insertpairwithstr(this->xli, (qse_xli_list_t*)pair->val, QSE_NULL, item.key, QSE_NULL, QSE_NULL, &v, QSE_NULL)) return -1;
}
this->accept_item_value (item, value);
return 0;
#else
// this function adds/updates the pair with the given value
// before it verifies the value. as long as verification is
// ok, the value is guaranteed to be set.
qse_cstr_t v = { (qse_char_t*)value, qse_strlen(value) };
qse_xli_pair_t* sctn_pair = QSE_NULL, * kv_pair = QSE_NULL;
sctn_pair = qse_xli_findpair(this->xli, QSE_NULL, item.sctn);
if (sctn_pair)
{
// section exists.
QSE_ASSERT (sctn_pair->val && sctn_pair->val->type == QSE_XLI_LIST);
kv_pair = qse_xli_findpair(this->xli, (qse_xli_list_t*)sctn_pair->val, item.key);
if (kv_pair)
{
// key also exists
qse_xli_pair_t* existing_kv_pair = kv_pair;
kv_pair = QSE_NULL;
sctn_pair = QSE_NULL;
qse_xli_str_t* newstrv = qse_xli_makestrval(this->xli, &v, QSE_NULL);
if (!newstrv) goto rollback;
if (this->call_probe_item_value(item, value) <= -1)
{
qse_xli_freeval (this->xli, (qse_xli_val_t*)newstrv);
goto rollback;
}
qse_xli_freeval (this->xli, existing_kv_pair->val);
existing_kv_pair->val = (qse_xli_val_t*)newstrv;
}
else
{
kv_pair = qse_xli_insertpairwithstr(this->xli, (qse_xli_list_t*)sctn_pair->val, QSE_NULL, item.key, QSE_NULL, QSE_NULL, &v, QSE_NULL);
sctn_pair = QSE_NULL;
if (!kv_pair) goto rollback;
if (this->call_probe_item_value(item, value) <= -1) goto rollback;
}
}
else
{
sctn_pair = qse_xli_insertpairwithemptylist(this->xli, QSE_NULL, QSE_NULL, item.sctn, QSE_NULL, QSE_NULL);
if (!sctn_pair) return -1;
kv_pair = qse_xli_insertpairwithstr(this->xli, (qse_xli_list_t*)sctn_pair->val, QSE_NULL, item.key, QSE_NULL, QSE_NULL, &v, QSE_NULL);
if (!kv_pair) goto rollback;
if (this->call_probe_item_value(item, value) <= -1) goto rollback;
}
return 0;
rollback:
if (kv_pair) qse_xli_deletepair (this->xli, kv_pair);
if (sctn_pair) qse_xli_deletepair (this->xli, sctn_pair);
return -1;
#endif
}
int SkvEnv::load (const qse_char_t* path)
@ -205,7 +271,7 @@ int SkvEnv::load (const qse_char_t* path)
if (!this->xli)
{
// this means that no items have been registered with
// this->addItem().
// this->addItem(). so loading is meaningless.
return -1;
}
@ -239,6 +305,7 @@ int SkvEnv::load (const qse_char_t* path)
}
}
// TODO: check if there are any unknown names. flag it via callbacks???
qse_xli_close(xli);
return 0;
}

View File

@ -24,7 +24,7 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "xli.h"
#include "xli-prv.h"
#include "../cmn/mem-prv.h"
const qse_char_t* qse_xli_dflerrstr (const qse_xli_t* xli, qse_xli_errnum_t errnum)

View File

@ -24,7 +24,7 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "xli.h"
#include "xli-prv.h"
#include <qse/cmn/chr.h>
/*

View File

@ -24,7 +24,7 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "xli.h"
#include "xli-prv.h"
#include <qse/cmn/chr.h>
/*

View File

@ -24,7 +24,7 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "xli.h"
#include "xli-prv.h"
#include <qse/cmn/chr.h>
static int get_token (qse_xli_t* xli);

View File

@ -24,7 +24,7 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "xli.h"
#include "xli-prv.h"
#include <qse/xli/stdxli.h>
#include <qse/cmn/path.h>
#include "../cmn/mem-prv.h"

View File

@ -24,7 +24,7 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "xli.h"
#include "xli-prv.h"
static int write_to_current_stream (qse_xli_t* xli, const qse_char_t* ptr, qse_size_t len)
{

View File

@ -24,7 +24,7 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "xli.h"
#include "xli-prv.h"
#include <qse/cmn/chr.h>
typedef struct arg_data_t arg_data_t;

View File

@ -24,7 +24,7 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "xli.h"
#include "xli-prv.h"
#include <qse/cmn/chr.h>
typedef struct arg_data_t arg_data_t;

View File

@ -24,7 +24,7 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "xli.h"
#include "xli-prv.h"
#include <qse/cmn/chr.h>
static qse_xli_root_list_t* make_root (qse_xli_t* xli);

View File

@ -29,6 +29,7 @@
#include <qse/cmn/main.h>
#include <qse/cmn/mbwc.h>
#include <qse/cmn/str.h>
#include <qse/cmn/String.hpp>
#include <locale.h>
#if defined(_WIN32)
@ -37,24 +38,32 @@
class MyEnv: public QSE::SkvEnv
{
public:
int probe_agent_name (const qse_char_t* name)
{
qse_printf (QSE_T("probing agent_name %s\n"), name);
return 0;
}
};
MyEnv myenv;
static int env_main (int argc, qse_char_t* argv[])
{
myenv.addItem (QSE_T("main*target"), QSE_T("file"), QSE_NULL);
myenv.addItem (QSE_T("main*targetq"), QSE_T("file"), QSE_NULL);
myenv.addItem (QSE_T("main*target"), QSE_T("file"));
myenv.addItem (QSE_T("main*targetq"), QSE_T("file"));
myenv.addItem (QSE_T("agent*name"), QSE_T("my-agent"), (MyEnv::ProbeProc)&MyEnv::probe_agent_name);
myenv.load (QSE_T("myenv.conf"));
//myenv.setValue(QSE_T("main*target"), QSE_T("qqqqqq"));
//myenv.setValue(QSE_T("main*target"), QSE_T("abcdefg"));
//myenv.setValue(QSE_T("main*targetq"), QSE_T("zozo"));
QSE::String x (myenv.getValue(QSE_T("main*target")));
x.append (QSE_T("-jj"));
myenv.setValue(QSE_T("main*target"), x);
const qse_char_t* v = myenv.getValue(QSE_T("main*target"));
qse_printf (QSE_T("%s\n"), (v? v: QSE_T("<null>")));
myenv.store (QSE_T("myenv.conf"));
myenv.store (QSE_T("myenv.conf"));
return 0;
}