ConfigSource: Implement line/stream parsing in base class to reduce code duplication
authorMichael Moon <triffid.hunter@gmail.com>
Sun, 3 Mar 2013 01:46:40 +0000 (12:46 +1100)
committerMichael Moon <triffid.hunter@gmail.com>
Mon, 4 Mar 2013 13:19:35 +0000 (00:19 +1100)
FileConfigSource: use base class parsing routines

src/libs/Config.cpp
src/libs/ConfigSource.h
src/libs/ConfigSources/FileConfigSource.cpp

index 7f7c8ca..0d97dfb 100644 (file)
@@ -84,13 +84,13 @@ void Config::config_cache_load(){
     // First element is a special empty ConfigValue for values not found
     ConfigValue* result = new ConfigValue;
     this->config_cache.push_back(result);
+
     // For each ConfigSource in our stack
     for( unsigned int i = 0; i < this->config_sources.size(); i++ ){
         ConfigSource* source = this->config_sources[i];
         source->transfer_values_to_cache(&this->config_cache);
     }
-    
+
     this->config_cache_loaded = true;
 }
 
@@ -127,7 +127,7 @@ ConfigValue* Config::value(uint16_t check_sum){
     check_sums[2] = 0x0000;
     return this->value(check_sums);
 }
-    
+
 // Get a value from the configuration as a string
 // Because we don't like to waste space in Flash with lengthy config parameter names, we take a checksum instead so that the name does not have to be stored
 // See get_checksum
@@ -135,7 +135,7 @@ ConfigValue* Config::value(uint16_t check_sums[]){
     ConfigValue* result = this->config_cache[0];
     bool cache_preloaded = this->config_cache_loaded;
     if( !cache_preloaded ){ this->config_cache_load(); }
-     
+
     for( unsigned int i=1; i<this->config_cache.size(); i++){
         // If this line matches the checksum
         bool match = true;
@@ -153,7 +153,7 @@ ConfigValue* Config::value(uint16_t check_sums[]){
         result = this->config_cache[i];
         break;
     }
-    
+
     if( !cache_preloaded ){
         this->config_cache_clear();
     }
index 0e2e017..d36d271 100644 (file)
@@ -27,6 +27,66 @@ class ConfigSource {
         virtual string read( uint16_t check_sums[3] ) = 0;
 
         uint16_t name_checksum;
+    protected:
+        virtual string process_char_from_ascii_config(int c, ConfigCache* cache) {
+            static string buffer;
+            if (c == '\n' || c == EOF)
+            {
+                // We have a new line
+                if( buffer[0] == '#' ){ buffer.clear(); return ""; } // Ignore comments
+                if( buffer.length() < 3 ){ buffer.clear(); return ""; } //Ignore empty lines
+                size_t begin_key = buffer.find_first_not_of(" ");
+                size_t begin_value = buffer.find_first_not_of(" ", buffer.find_first_of(" ", begin_key));
+
+                uint16_t check_sums[3];
+                get_checksums(check_sums, buffer.substr(begin_key,  buffer.find_first_of(" ", begin_key) - begin_key).append(" "));
+
+                ConfigValue* result = new ConfigValue;
+
+                result->found = true;
+                result->check_sums[0] = check_sums[0];
+                result->check_sums[1] = check_sums[1];
+                result->check_sums[2] = check_sums[2];
+
+                result->value = buffer.substr(begin_value, buffer.find_first_of("\r\n# ", begin_value+1)-begin_value);
+                // Append the newly found value to the cache we were passed
+                cache->replace_or_push_back(result);
+
+                buffer.clear();
+
+                return result->value;
+            }
+            else
+                buffer += c;
+
+            return "";
+        };
+        virtual string process_char_from_ascii_config(int c, uint16_t line_checksums[3]) {
+            static string buffer;
+            string value;
+            if (c == '\n' || c == EOF)
+            {
+                // We have a new line
+                if( buffer[0] == '#' ){ buffer.clear(); return ""; } // Ignore comments
+                if( buffer.length() < 3 ){ buffer.clear(); return ""; } //Ignore empty lines
+                size_t begin_key = buffer.find_first_not_of(" ");
+                size_t begin_value = buffer.find_first_not_of(" ", buffer.find_first_of(" ", begin_key));
+
+                uint16_t check_sums[3];
+                get_checksums(check_sums, buffer.substr(begin_key,  buffer.find_first_of(" ", begin_key) - begin_key).append(" "));
+
+                if(check_sums[0] == line_checksums[0] && check_sums[1] == line_checksums[1] && check_sums[2] == line_checksums[2] ){
+                    value = buffer.substr(begin_value, buffer.find_first_of("\r\n# ", begin_value+1)-begin_value);
+                    buffer.clear();
+                    return value;
+                }
+
+                buffer.clear();
+            }
+            else
+                buffer += c;
+            return value;
+        };
 };
 
 
index 92a345a..5006e4d 100644 (file)
@@ -25,44 +25,13 @@ FileConfigSource::FileConfigSource(string config_file, uint16_t name_checksum){
 // Transfer all values found in the file to the passed cache
 void FileConfigSource::transfer_values_to_cache( ConfigCache* cache ){
 
-    // Default empty value
-    ConfigValue* result = new ConfigValue;
-
     if( this->has_config_file() == false ){return;}
     // Open the config file ( find it if we haven't already found it )
     FILE *lp = fopen(this->get_config_file().c_str(), "r");
-    string buffer;
     int c;
     // For each line
     do {
-        c = fgetc (lp);
-        if (c == '\n' || c == EOF){
-
-            // We have a new line
-            if( buffer[0] == '#' ){ buffer.clear(); continue; } // Ignore comments
-            if( buffer.length() < 3 ){ buffer.clear(); continue; } //Ignore empty lines
-            size_t begin_key = buffer.find_first_not_of(" ");
-            size_t begin_value = buffer.find_first_not_of(" ", buffer.find_first_of(" ", begin_key));
-
-            uint16_t check_sums[3];
-            get_checksums(check_sums, buffer.substr(begin_key,  buffer.find_first_of(" ", begin_key) - begin_key).append(" "));
-
-            result = new ConfigValue;
-
-            result->found = true;
-            result->check_sums[0] = check_sums[0];
-            result->check_sums[1] = check_sums[1];
-            result->check_sums[2] = check_sums[2];
-
-            result->value = buffer.substr(begin_value, buffer.find_first_of("\r\n# ", begin_value+1)-begin_value);
-            // Append the newly found value to the cache we were passed
-            cache->replace_or_push_back(result);
-
-            buffer.clear();
-
-        }else{
-            buffer += c;
-        }
+        process_char_from_ascii_config(c = fgetc(lp), cache);
     } while (c != EOF);
     fclose(lp);
 }
@@ -121,31 +90,11 @@ string FileConfigSource::read( uint16_t check_sums[3] ){
     if( this->has_config_file() == false ){return value;}
     // Open the config file ( find it if we haven't already found it )
     FILE *lp = fopen(this->get_config_file().c_str(), "r");
-    string buffer;
     int c;
     // For each line
     do {
         c = fgetc (lp);
-        if (c == '\n' || c == EOF){
-            // We have a new line
-            if( buffer[0] == '#' ){ buffer.clear(); continue; } // Ignore comments
-            if( buffer.length() < 3 ){ buffer.clear(); continue; } //Ignore empty lines
-            size_t begin_key = buffer.find_first_not_of(" \t");
-            size_t begin_value = buffer.find_first_not_of(" \t", buffer.find_first_of(" \t", begin_key));
-            string key = buffer.substr(begin_key,  buffer.find_first_of(" \t", begin_key) - begin_key).append(" ");
-
-            uint16_t line_checksums[3];
-            get_checksums(line_checksums, key);
-
-            if(check_sums[0] == line_checksums[0] && check_sums[1] == line_checksums[1] && check_sums[2] == line_checksums[2] ){
-                value = buffer.substr(begin_value, buffer.find_first_of("\r\n# ", begin_value+1)-begin_value);
-                break;
-            }
-
-            buffer.clear();
-        }else{
-            buffer += c;
-        }
+        process_char_from_ascii_config(c, check_sums);
     } while (c != EOF);
     fclose(lp);