The key and value pairs config wrapper class for managing app setting.

Dependents:   dconfig_demo mbed_controller_demo

Files at this revision

API Documentation at this revision

Comitter:
hillkim7
Date:
Tue Feb 24 15:48:43 2015 +0000
Parent:
0:7e982de4d3f5
Child:
2:989178d925e9
Commit message:
Provide function to specify delimiters for data load/save.

Changed in this revision

dconfig.cpp Show annotated file Show diff for this revision Revisions of this file
dconfig.h Show annotated file Show diff for this revision Revisions of this file
--- a/dconfig.cpp	Tue Feb 17 14:37:18 2015 +0000
+++ b/dconfig.cpp	Tue Feb 24 15:48:43 2015 +0000
@@ -1,106 +1,161 @@
-/**
-* @file dconfig.h
-*
-* @author hillkim7@gmail.com
-* @brief The key and value pairs config wrapper class for managing app setting.
-*
-*/
-
-#include <string.h>
-#include <stdlib.h>
-#include "dconfig.h"
-
-int DConfig::lookup_as_int( const std::string &key_name, int default_value ) const
-{
-    std::string val;
-
-    if (lookup(key_name, val))
-        return atoi(val.c_str());
-    else
-        return default_value;
-}
-
-const char * DConfig::lookup_as_cstr( const std::string &key_name, const char *default_value ) const
-{
-    std::map<std::string, std::string>::const_iterator it = this->find(key_name);
-    if (it != this->end())
-        return it->second.c_str();
-
-    return default_value;
-}
-
-bool DConfig::lookup( const std::string &key_name, std::string &value ) const
-{
-    std::map<std::string, std::string>::const_iterator it = this->find(key_name);
-    if (it != this->end())
-    {
-        value = it->second;
-        return true;
-    }
-
-    return false;
-}
-
-std::string DConfig::lookup( const std::string &key_name ) const
-{
-    std::string s;
-
-    lookup(key_name, s);
-
-    return s;
-}
-
-bool DConfig::load_from( const char *ptr, size_t ptr_len )
-{
-    const char *end = ptr + ptr_len;
-    const char *key, *val;
-
-    while (ptr < end)
-    {
-        key = ptr;
-        while (*ptr)    // go until the end of C string
-            ptr++;
-
-        if (++ptr >= end)
-        {
-            return false;
-        }
-
-        val = ptr;
-        while (*ptr)    // go until the end of C string
-            ptr++;
-        if (++ptr > end)
-        {
-            return false;
-        }
-
-        (*this)[key] = val;
-    }
-
-    return true;
-}
-
-static bool put_cstring(DConfigOutput_t func, void *user_data, const char *s)
-{
-    while (*s && func(user_data, *s))
-        s++;
-
-    return func(user_data, '\0');
-}
-
-bool DConfig::save_to( DConfigOutput_t func, void *user_data ) const
-{
-    for (std::map<std::string, std::string>::const_iterator it = this->begin();
-        it != this->end(); ++it)
-    {
-        if (!put_cstring(func, user_data, it->first.c_str()))
-            return false;
-
-        if (!put_cstring(func, user_data, it->second.c_str()))
-            return false;
-    }
-
-    return true;
-}
-
+/**
+* @file dconfig.h
+*
+* @author hillkim7@gmail.com
+* @brief The key and value pairs config wrapper class for managing app setting.
+*
+*/
+
+#include <string.h>
+#include <stdio.h>
+#include "dconfig.h"
+
+int DConfig::lookup_as_int( const std::string &key_name, int default_value ) const
+{
+    std::string val;
+
+    if (lookup(key_name, val))
+        return atoi(val.c_str());
+    else
+        return default_value;
+}
+
+const char * DConfig::lookup_as_cstr( const std::string &key_name, const char *default_value ) const
+{
+    std::map<std::string, std::string>::const_iterator it = this->find(key_name);
+    if (it != this->end())
+        return it->second.c_str();
+
+    return default_value;
+}
+
+bool DConfig::lookup( const std::string &key_name, std::string &value ) const
+{
+    std::map<std::string, std::string>::const_iterator it = this->find(key_name);
+    if (it != this->end())
+    {
+        value = it->second;
+        return true;
+    }
+
+    return false;
+}
+
+std::string DConfig::lookup( const std::string &key_name ) const
+{
+    std::string s;
+
+    lookup(key_name, s);
+
+    return s;
+}
+
+bool DConfig::load_from( const char *ptr, size_t ptr_len, char kv_delimiter, char item_delimiter )
+{
+    const char *end = ptr + ptr_len;
+    const char *begin;
+    std::string str_key, str_value;
+
+    while (ptr < end)
+    {
+        // load key part
+        begin = ptr;
+        while (*ptr != kv_delimiter)    // go until it reaches delimiter
+        {
+            ptr++;
+            if (ptr > end)
+            {
+                return false;
+            }
+        }
+
+        std::string key(begin, ptr);
+        ++ptr;  // skip delimiter
+        if (ptr >= end)
+        {
+            return false;
+        }
 
+        // load value part
+        begin = ptr;
+        while (*ptr != item_delimiter)
+        {
+            ptr++;
+            if (ptr > end)
+            {
+                return false;
+            }
+        }
+
+        std::string val(begin, ptr);
+        ++ptr;
+        if (ptr > end)
+        {
+            return false;
+        }
+
+        (*this)[key] = val;
+    }
+
+    return true;
+}
+
+static bool put_cstring(DConfigOutput_t func, void *user_data, const char *s, char delimiter)
+{
+    while (*s && func(user_data, *s))
+        s++;
+
+    return func(user_data, delimiter);
+}
+
+bool DConfig::save_to( DConfigOutput_t func, void *user_data, char kv_delimiter, char item_delimiter ) const
+{
+    for (std::map<std::string, std::string>::const_iterator it = this->begin();
+        it != this->end(); ++it)
+    {
+        if (!put_cstring(func, user_data, it->first.c_str(), kv_delimiter))
+            return false;
+
+        if (!put_cstring(func, user_data, it->second.c_str(), item_delimiter))
+            return false;
+    }
+
+    return true;
+}
+
+static bool count_config(void *user_data, char c)
+{
+    size_t *cnt = (size_t*)user_data;
+
+    *cnt += 1;
+
+    return true;
+}
+
+size_t DConfig::estimate_save( void ) const
+{
+    size_t cnt = 0;
+
+    save_to(count_config, &cnt);
+
+    return cnt;
+}
+
+bool DConfig::value_replace( const std::string &key_name, std::string value )
+{
+    if (!has_key(key_name))
+        return false;
+
+    (*this)[key_name] = value;
+
+    return true;
+}
+
+bool DConfig::value_replace( const std::string &key_name, int value )
+{
+    char tmp[16];
+
+    sprintf(tmp, "%d", value);
+
+    return value_replace(key_name, tmp);
+}
--- a/dconfig.h	Tue Feb 17 14:37:18 2015 +0000
+++ b/dconfig.h	Tue Feb 24 15:48:43 2015 +0000
@@ -49,36 +49,49 @@
 class DConfig : public std::map<std::string, std::string>
 {
 public:
-    /*** lookup value by key and return value as int if a key exists. */
+    /** lookup value by key and return value as int if a key exists. */
     int lookup_as_int(const std::string &key_name, int default_value) const;
 
-    /*** lookup value by key and return value as C string if a key exists. */
+    /** lookup value by key and return value as C string if a key exists. */
     const char *lookup_as_cstr(const std::string &key_name, const char *default_value) const;
 
-    /*** lookup value by key */
+    /** lookup value by key */
     bool lookup(const std::string &key_name, std::string &value) const;
 
-    /*** lookup value by key and return value as C string if a key exists. */
+    /** lookup value by key and return value as C string if a key exists. */
     std::string lookup(const std::string &key_name) const;
 
-    /*** load key & value pairs from memory.
-    * Both key and value are saved in the form of C string which includes null terminated char('\0').
-    */
-    bool load_from(const char *ptr, size_t ptr_len);
+    /** replace value of existing value matching key. */
+    bool value_replace(const std::string &key_name, std::string value);
+
+    /** replace value of existing value matching key. */
+    bool value_replace(const std::string &key_name, int value);
 
-    /*** save all key & value pairs by calling callback function. */
-    bool save_to(DConfigOutput_t func, void *user_data) const;
+    /** load key & value pairs from memory.
+    * The delimiters are same as them used in the load_from().
+    * @param kv_delimiter delimiter char between key and value.
+    * @param item_delimiter delimiter char between items.
+    */
+    bool load_from(const char *ptr, size_t ptr_len, char kv_delimiter='=', char item_delimiter='\n');
 
-    /*** Check if a key exists. */
+    /** save all key & value pairs by calling callback function.
+    * @param kv_delimiter delimiter char between key and value.
+    * @param item_delimiter delimiter char between items.
+    */
+    bool save_to(DConfigOutput_t func, void *user_data, char kv_delimiter='=', char item_delimiter='\n') const;
+
+    /** estimate number of bytes for saving */
+    size_t estimate_save(void) const;
+
+    /** check if a key exists. */
     bool has_key(const std::string &key_name) const
     {
         return this->find(key_name) != this->end();
     }
 
-    /*** virtual function for default setting. */
+    /** virtual function for default setting. */
     virtual void reset_default(void)
     {
     }
 };
 
-