Use new NfcConfig parser (1/2)
am: a34d7d13a2

Change-Id: Ib9f3adc1a5bff49d26b90add0794969e4446fce7
diff --git a/src/adaptation/NfcAdaptation.cc b/src/adaptation/NfcAdaptation.cc
index 5d97ed0..f497ae0 100644
--- a/src/adaptation/NfcAdaptation.cc
+++ b/src/adaptation/NfcAdaptation.cc
@@ -25,9 +25,9 @@
 #include "NfcAdaptation.h"
 
 #include "android_logmsg.h"
-#include "config.h"
 #include "debug_nfcsnoop.h"
 #include "nfa_api.h"
+#include "nfc_config.h"
 #include "nfc_int.h"
 #include "nfca_version.h"
 
@@ -46,7 +46,6 @@
 extern bool nfc_debug_enabled;
 
 extern void GKI_shutdown();
-extern void resetConfig();
 extern void verify_stack_non_volatile_store();
 extern void delete_stack_non_volatile_store(bool forceDelete);
 
@@ -60,31 +59,33 @@
 INfcClientCallback* NfcAdaptation::mCallback;
 
 bool nfc_debug_enabled = false;
+std::string nfc_storage_path;
 uint8_t appl_dta_mode_flag = 0x00;
-char bcm_nfc_location[120];
 
-static uint8_t nfa_dm_cfg[sizeof(tNFA_DM_CFG)];
-static uint8_t nfa_proprietary_cfg[sizeof(tNFA_PROPRIETARY_CFG)];
-extern tNFA_DM_CFG* p_nfa_dm_cfg;
-extern tNFA_PROPRIETARY_CFG* p_nfa_proprietary_cfg;
+extern tNFA_DM_CFG nfa_dm_cfg;
+extern tNFA_PROPRIETARY_CFG nfa_proprietary_cfg;
+extern tNFA_HCI_CFG nfa_hci_cfg;
 extern uint8_t nfa_ee_max_ee_cfg;
+extern bool nfa_poll_bail_out_mode;
+
 extern const uint8_t nfca_version_string[];
 extern const uint8_t nfa_version_string[];
-static uint8_t deviceHostWhiteList[NFA_HCI_MAX_HOST_IN_NETWORK];
-static tNFA_HCI_CFG jni_nfa_hci_cfg;
-extern tNFA_HCI_CFG* p_nfa_hci_cfg;
-extern bool nfa_poll_bail_out_mode;
+
+// Whitelist for hosts allowed to create a pipe
+// See ADM_CREATE_PIPE command in the ETSI test specification
+// ETSI TS 102 622, section 6.1.3.1
+static std::vector<uint8_t> host_whitelist;
 
 namespace {
 void initializeGlobalDebugEnabledFlag() {
-  unsigned trace_level = 1;
-  if (GetNumValue(NAME_APPL_TRACE_LEVEL, &trace_level, sizeof(trace_level)))
-    nfc_debug_enabled = (trace_level == 0) ? false : true;
+  nfc_debug_enabled =
+      (NfcConfig::getUnsigned(NAME_NFC_DEBUG_ENABLED, 0) != 0) ? true : false;
 
   char valueStr[PROPERTY_VALUE_MAX] = {0};
   int len = property_get("nfc.app_log_level", valueStr, "");
   if (len > 0) {
     // let Android property override .conf variable
+    unsigned trace_level = 0;
     sscanf(valueStr, "%u", &trace_level);
     nfc_debug_enabled = (trace_level == 0) ? false : true;
   }
@@ -171,7 +172,6 @@
 *******************************************************************************/
 void NfcAdaptation::Initialize() {
   const char* func = "NfcAdaptation::Initialize";
-  unsigned long num;
   const char* argv[] = {"libnfc_nci"};
   // Init log tag
   base::CommandLine::Init(1, argv);
@@ -183,60 +183,73 @@
   LOG(INFO) << StringPrintf("%s: ver=%s nfa=%s", func, nfca_version_string,
                             nfa_version_string);
 
-  if (GetNumValue(NAME_USE_RAW_NCI_TRACE, &num, sizeof(num))) {
-    if (num == 1) {
-      DLOG_IF(INFO, nfc_debug_enabled)
-          << StringPrintf("%s: logging protocol in raw format", func);
-    }
-  }
-  if (!GetStrValue(NAME_NFA_STORAGE, bcm_nfc_location,
-                   sizeof(bcm_nfc_location))) {
-    strlcpy(bcm_nfc_location, "/data/nfc", sizeof(bcm_nfc_location));
+  nfc_storage_path = NfcConfig::getString(NAME_NFA_STORAGE, "/data/nfc");
+
+  if (NfcConfig::hasKey(NAME_NFA_DM_CFG)) {
+    std::vector<uint8_t> dm_config = NfcConfig::getBytes(NAME_NFA_DM_CFG);
+    if (dm_config.size() > 0) nfa_dm_cfg.auto_detect_ndef = dm_config[0];
+    if (dm_config.size() > 1) nfa_dm_cfg.auto_read_ndef = dm_config[1];
+    if (dm_config.size() > 2) nfa_dm_cfg.auto_presence_check = dm_config[2];
+    if (dm_config.size() > 3) nfa_dm_cfg.presence_check_option = dm_config[3];
+    // NOTE: The timeout value is not configurable here because the endianess
+    // of a byte array is ambiguous and needlessly difficult to configure.
+    // If this value needs to be configgurable, a numeric config option should
+    // be used.
   }
 
-  if (GetStrValue(NAME_NFA_DM_CFG, (char*)nfa_dm_cfg, sizeof(nfa_dm_cfg)))
-    p_nfa_dm_cfg = (tNFA_DM_CFG*)&nfa_dm_cfg[0];
-
-  if (GetNumValue(NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof(num))) {
-    nfa_ee_max_ee_cfg = num;
+  if (NfcConfig::hasKey(NAME_NFA_MAX_EE_SUPPORTED)) {
+    nfa_ee_max_ee_cfg = NfcConfig::getUnsigned(NAME_NFA_MAX_EE_SUPPORTED);
     DLOG_IF(INFO, nfc_debug_enabled)
         << StringPrintf("%s: Overriding NFA_EE_MAX_EE_SUPPORTED to use %d",
                         func, nfa_ee_max_ee_cfg);
   }
-  if (GetNumValue(NAME_NFA_POLL_BAIL_OUT_MODE, &num, sizeof(num))) {
-    nfa_poll_bail_out_mode = num;
+
+  if (NfcConfig::hasKey(NAME_NFA_POLL_BAIL_OUT_MODE)) {
+    nfa_poll_bail_out_mode =
+        NfcConfig::getUnsigned(NAME_NFA_POLL_BAIL_OUT_MODE);
     DLOG_IF(INFO, nfc_debug_enabled)
         << StringPrintf("%s: Overriding NFA_POLL_BAIL_OUT_MODE to use %d", func,
                         nfa_poll_bail_out_mode);
   }
 
-  if (GetStrValue(NAME_NFA_PROPRIETARY_CFG, (char*)nfa_proprietary_cfg,
-                  sizeof(tNFA_PROPRIETARY_CFG))) {
-    p_nfa_proprietary_cfg = (tNFA_PROPRIETARY_CFG*)&nfa_proprietary_cfg[0];
+  if (NfcConfig::hasKey(NAME_NFA_PROPRIETARY_CFG)) {
+    std::vector<uint8_t> p_config =
+        NfcConfig::getBytes(NAME_NFA_PROPRIETARY_CFG);
+    if (p_config.size() > 0)
+      nfa_proprietary_cfg.pro_protocol_18092_active = p_config[0];
+    if (p_config.size() > 1)
+      nfa_proprietary_cfg.pro_protocol_b_prime = p_config[1];
+    if (p_config.size() > 2)
+      nfa_proprietary_cfg.pro_protocol_dual = p_config[2];
+    if (p_config.size() > 3)
+      nfa_proprietary_cfg.pro_protocol_15693 = p_config[3];
+    if (p_config.size() > 4)
+      nfa_proprietary_cfg.pro_protocol_kovio = p_config[4];
+    if (p_config.size() > 5) nfa_proprietary_cfg.pro_protocol_mfc = p_config[5];
+    if (p_config.size() > 6)
+      nfa_proprietary_cfg.pro_discovery_kovio_poll = p_config[6];
+    if (p_config.size() > 7)
+      nfa_proprietary_cfg.pro_discovery_b_prime_poll = p_config[7];
+    if (p_config.size() > 8)
+      nfa_proprietary_cfg.pro_discovery_b_prime_listen = p_config[8];
   }
 
-  // configure device host whitelist of HCI host ID's; see specification ETSI TS
-  // 102 622 V11.1.10
-  //(2012-10), section 6.1.3.1
-  num = GetStrValue(NAME_DEVICE_HOST_WHITE_LIST, (char*)deviceHostWhiteList,
-                    sizeof(deviceHostWhiteList));
-  if (num) {
-    memmove(&jni_nfa_hci_cfg, p_nfa_hci_cfg, sizeof(jni_nfa_hci_cfg));
-    jni_nfa_hci_cfg.num_whitelist_host =
-        (uint8_t)num;  // number of HCI host ID's in the whitelist
-    jni_nfa_hci_cfg.p_whitelist = deviceHostWhiteList;  // array of HCI host
-                                                        // ID's
-    p_nfa_hci_cfg = &jni_nfa_hci_cfg;
+  // Configure whitelist of HCI host ID's
+  // See specification: ETSI TS 102 622, section 6.1.3.1
+  if (NfcConfig::hasKey(NAME_DEVICE_HOST_WHITE_LIST)) {
+    host_whitelist = NfcConfig::getBytes(NAME_DEVICE_HOST_WHITE_LIST);
+    nfa_hci_cfg.num_whitelist_host = host_whitelist.size();
+    nfa_hci_cfg.p_whitelist = &host_whitelist[0];
   }
 
   initializeGlobalDebugEnabledFlag();
 
   verify_stack_non_volatile_store();
-  if (GetNumValue(NAME_PRESERVE_STORAGE, (char*)&num, sizeof(num)) &&
-      (num == 1))
+  if (NfcConfig::hasKey(NAME_PRESERVE_STORAGE) &&
+      NfcConfig::getUnsigned(NAME_PRESERVE_STORAGE) == 1) {
     DLOG_IF(INFO, nfc_debug_enabled)
         << StringPrintf("%s: preserve stack NV store", __func__);
-  else {
+  } else {
     delete_stack_non_volatile_store(FALSE);
   }
 
@@ -274,7 +287,7 @@
   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", func);
   GKI_shutdown();
 
-  resetConfig();
+  NfcConfig::clear();
 
   mCallback = NULL;
   memset(&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
diff --git a/src/adaptation/config.cc b/src/adaptation/config.cc
deleted file mode 100644
index 3413a2d..0000000
--- a/src/adaptation/config.cc
+++ /dev/null
@@ -1,689 +0,0 @@
-/******************************************************************************
- *
- *  Copyright (C) 2011-2012 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at:
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-#include <stdio.h>
-#include <sys/stat.h>
-#include <list>
-#include <string>
-#include <vector>
-
-#include <android-base/stringprintf.h>
-#include <base/logging.h>
-
-using android::base::StringPrintf;
-
-extern bool nfc_debug_enabled;
-
-const char* transport_config_paths[] = {"/odm/etc/", "/vendor/etc/", "/etc/"};
-const int transport_config_path_size =
-    (sizeof(transport_config_paths) / sizeof(transport_config_paths[0]));
-
-#define config_name "libnfc-brcm.conf"
-#define extra_config_base "libnfc-brcm-"
-#define extra_config_ext ".conf"
-#define IsStringValue 0x80000000
-
-using namespace ::std;
-
-class CNfcParam : public string {
- public:
-  CNfcParam();
-  CNfcParam(const char* name, const string& value);
-  CNfcParam(const char* name, unsigned long value);
-  virtual ~CNfcParam();
-  unsigned long numValue() const { return m_numValue; }
-  const char* str_value() const { return m_str_value.c_str(); }
-  size_t str_len() const { return m_str_value.length(); }
-
- private:
-  string m_str_value;
-  unsigned long m_numValue;
-};
-
-class CNfcConfig : public vector<const CNfcParam*> {
- public:
-  virtual ~CNfcConfig();
-  static CNfcConfig& GetInstance();
-  friend void readOptionalConfig(const char* optional);
-
-  bool getValue(const char* name, char* pValue, size_t& len) const;
-  bool getValue(const char* name, unsigned long& rValue) const;
-  bool getValue(const char* name, unsigned short& rValue) const;
-  const CNfcParam* find(const char* p_name) const;
-  void clean();
-
- private:
-  CNfcConfig();
-  bool readConfig(const char* name, bool bResetContent);
-  void moveFromList();
-  void moveToList();
-  void add(const CNfcParam* pParam);
-  list<const CNfcParam*> m_list;
-  bool mValidFile;
-
-  unsigned long state;
-
-  inline bool Is(unsigned long f) { return (state & f) == f; }
-  inline void Set(unsigned long f) { state |= f; }
-};
-
-/*******************************************************************************
-**
-** Function:    isPrintable()
-**
-** Description: detremine if a char is printable
-**
-** Returns:     none
-**
-*******************************************************************************/
-inline bool isPrintable(char c) {
-  return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
-         (c >= '0' && c <= '9') || c == '/' || c == '_' || c == '-' || c == '.';
-}
-
-/*******************************************************************************
-**
-** Function:    isDigit()
-**
-** Description: detremine if a char is numeral digit
-**
-** Returns:     none
-**
-*******************************************************************************/
-inline bool isDigit(char c, int base) {
-  if ('0' <= c && c <= '9') return true;
-  if (base == 16) {
-    if (('A' <= c && c <= 'F') || ('a' <= c && c <= 'f')) return true;
-  }
-  return false;
-}
-
-/*******************************************************************************
-**
-** Function:    getDigitValue()
-**
-** Description: return numercal value of a char
-**
-** Returns:     none
-**
-*******************************************************************************/
-inline int getDigitValue(char c, int base) {
-  if ('0' <= c && c <= '9') return c - '0';
-  if (base == 16) {
-    if ('A' <= c && c <= 'F')
-      return c - 'A' + 10;
-    else if ('a' <= c && c <= 'f')
-      return c - 'a' + 10;
-  }
-  return 0;
-}
-
-/*******************************************************************************
-**
-** Function:    findConfigFilePathFromTransportConfigPaths()
-**
-** Description: find a config file path with a given config name from transport
-**              config paths
-**
-** Returns:     none
-**
-*******************************************************************************/
-void findConfigFilePathFromTransportConfigPaths(const string& configName,
-                                                string& filePath) {
-  for (int i = 0; i < transport_config_path_size - 1; i++) {
-    filePath.assign(transport_config_paths[i]);
-    filePath += configName;
-    struct stat file_stat;
-    if (stat(filePath.c_str(), &file_stat) == 0 && S_ISREG(file_stat.st_mode)) {
-      return;
-    }
-  }
-  filePath.assign(transport_config_paths[transport_config_path_size - 1]);
-  filePath += configName;
-}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::readConfig()
-**
-** Description: read Config settings and parse them into a linked list
-**              move the element from linked list to a array at the end
-**
-** Returns:     none
-**
-*******************************************************************************/
-bool CNfcConfig::readConfig(const char* name, bool bResetContent) {
-  enum {
-    BEGIN_LINE = 1,
-    TOKEN,
-    STR_VALUE,
-    NUM_VALUE,
-    BEGIN_HEX,
-    BEGIN_QUOTE,
-    END_LINE
-  };
-
-  FILE* fd = NULL;
-  string token;
-  string strValue;
-  unsigned long numValue = 0;
-  CNfcParam* pParam = NULL;
-  int i = 0;
-  int base = 0;
-  char c = 0;
-
-  state = BEGIN_LINE;
-  /* open config file, read it into a buffer */
-  if ((fd = fopen(name, "rb")) == NULL) {
-    DLOG_IF(INFO, nfc_debug_enabled)
-        << StringPrintf("%s Cannot open config file %s", __func__, name);
-    if (bResetContent) {
-      DLOG_IF(INFO, nfc_debug_enabled)
-          << StringPrintf("%s Using default value for all settings", __func__);
-      mValidFile = false;
-    }
-    return false;
-  }
-  DLOG_IF(INFO, nfc_debug_enabled)
-      << StringPrintf("%s Opened %s config %s", __func__,
-                      (bResetContent ? "base" : "optional"), name);
-
-  mValidFile = true;
-  if (size() > 0) {
-    if (bResetContent)
-      clean();
-    else
-      moveToList();
-  }
-
-  for (;;) {
-    if (feof(fd) || fread(&c, 1, 1, fd) != 1) {
-      if (state == BEGIN_LINE) break;
-
-      // got to the EOF but not in BEGIN_LINE state so the file
-      // probably does not end with a newline, so the parser has
-      // not processed current line, simulate a newline in the file
-      c = '\n';
-    }
-
-    switch (state & 0xff) {
-      case BEGIN_LINE:
-        if (c == '#')
-          state = END_LINE;
-        else if (isPrintable(c)) {
-          i = 0;
-          token.erase();
-          strValue.erase();
-          state = TOKEN;
-          token.push_back(c);
-        }
-        break;
-      case TOKEN:
-        if (c == '=') {
-          token.push_back('\0');
-          state = BEGIN_QUOTE;
-        } else if (isPrintable(c))
-          token.push_back(c);
-        else
-          state = END_LINE;
-        break;
-      case BEGIN_QUOTE:
-        if (c == '"') {
-          state = STR_VALUE;
-          base = 0;
-        } else if (c == '0')
-          state = BEGIN_HEX;
-        else if (isDigit(c, 10)) {
-          state = NUM_VALUE;
-          base = 10;
-          numValue = getDigitValue(c, base);
-          i = 0;
-        } else if (c == '{') {
-          state = NUM_VALUE;
-          base = 16;
-          i = 0;
-          Set(IsStringValue);
-        } else
-          state = END_LINE;
-        break;
-      case BEGIN_HEX:
-        if (c == 'x' || c == 'X') {
-          state = NUM_VALUE;
-          base = 16;
-          numValue = 0;
-          i = 0;
-          break;
-        } else if (isDigit(c, 10)) {
-          state = NUM_VALUE;
-          base = 10;
-          numValue = getDigitValue(c, base);
-          break;
-        } else if (c != '\n' && c != '\r') {
-          state = END_LINE;
-          break;
-        }
-      // fal through to numValue to handle numValue
-
-      case NUM_VALUE:
-        if (isDigit(c, base)) {
-          numValue *= base;
-          numValue += getDigitValue(c, base);
-          ++i;
-        } else if (base == 16 &&
-                   (c == ':' || c == '-' || c == ' ' || c == '}')) {
-          if (i > 0) {
-            int n = (i + 1) / 2;
-            while (n-- > 0) {
-              unsigned char c = (numValue >> (n * 8)) & 0xFF;
-              strValue.push_back(c);
-            }
-          }
-          Set(IsStringValue);
-          numValue = 0;
-          i = 0;
-        } else {
-          if (c == '\n' || c == '\r')
-            state = BEGIN_LINE;
-          else
-            state = END_LINE;
-          if (Is(IsStringValue) && base == 16 && i > 0) {
-            int n = (i + 1) / 2;
-            while (n-- > 0) strValue.push_back(((numValue >> (n * 8)) & 0xFF));
-          }
-          if (strValue.length() > 0)
-            pParam = new CNfcParam(token.c_str(), strValue);
-          else
-            pParam = new CNfcParam(token.c_str(), numValue);
-          add(pParam);
-          strValue.erase();
-          numValue = 0;
-        }
-        break;
-      case STR_VALUE:
-        if (c == '"') {
-          strValue.push_back('\0');
-          state = END_LINE;
-          pParam = new CNfcParam(token.c_str(), strValue);
-          add(pParam);
-        } else if (isPrintable(c))
-          strValue.push_back(c);
-        break;
-      case END_LINE:
-        if (c == '\n' || c == '\r') state = BEGIN_LINE;
-        break;
-      default:
-        break;
-    }
-
-    if (feof(fd)) break;
-  }
-
-  fclose(fd);
-
-  moveFromList();
-  return size() > 0;
-}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::CNfcConfig()
-**
-** Description: class constructor
-**
-** Returns:     none
-**
-*******************************************************************************/
-CNfcConfig::CNfcConfig() : mValidFile(true), state(0) {}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::~CNfcConfig()
-**
-** Description: class destructor
-**
-** Returns:     none
-**
-*******************************************************************************/
-CNfcConfig::~CNfcConfig() {}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::GetInstance()
-**
-** Description: get class singleton object
-**
-** Returns:     none
-**
-*******************************************************************************/
-CNfcConfig& CNfcConfig::GetInstance() {
-  static CNfcConfig theInstance;
-
-  if (theInstance.size() == 0 && theInstance.mValidFile) {
-    string strPath;
-    findConfigFilePathFromTransportConfigPaths(config_name, strPath);
-    theInstance.readConfig(strPath.c_str(), true);
-  }
-
-  return theInstance;
-}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::getValue()
-**
-** Description: get a string value of a setting
-**
-** Returns:     true if setting exists
-**              false if setting does not exist
-**
-*******************************************************************************/
-bool CNfcConfig::getValue(const char* name, char* pValue, size_t& len) const {
-  const CNfcParam* pParam = find(name);
-  if (pParam == NULL) return false;
-
-  if (pParam->str_len() > 0) {
-    memset(pValue, 0, len);
-    if (len > pParam->str_len()) len = pParam->str_len();
-    memcpy(pValue, pParam->str_value(), len);
-    return true;
-  }
-  return false;
-}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::getValue()
-**
-** Description: get a long numerical value of a setting
-**
-** Returns:     true if setting exists
-**              false if setting does not exist
-**
-*******************************************************************************/
-bool CNfcConfig::getValue(const char* name, unsigned long& rValue) const {
-  const CNfcParam* pParam = find(name);
-  if (pParam == NULL) return false;
-
-  if (pParam->str_len() == 0) {
-    rValue = static_cast<unsigned long>(pParam->numValue());
-    return true;
-  }
-  return false;
-}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::getValue()
-**
-** Description: get a short numerical value of a setting
-**
-** Returns:     true if setting exists
-**              false if setting does not exist
-**
-*******************************************************************************/
-bool CNfcConfig::getValue(const char* name, unsigned short& rValue) const {
-  const CNfcParam* pParam = find(name);
-  if (pParam == NULL) return false;
-
-  if (pParam->str_len() == 0) {
-    rValue = static_cast<unsigned short>(pParam->numValue());
-    return true;
-  }
-  return false;
-}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::find()
-**
-** Description: search if a setting exist in the setting array
-**
-** Returns:     pointer to the setting object
-**
-*******************************************************************************/
-const CNfcParam* CNfcConfig::find(const char* p_name) const {
-  if (size() == 0) return NULL;
-
-  for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it) {
-    if (**it < p_name)
-      continue;
-    else if (**it == p_name) {
-      if ((*it)->str_len() > 0)
-        DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
-            "%s found %s=%s", __func__, p_name, (*it)->str_value());
-      else
-        DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
-            "%s found %s=(0x%lX)", __func__, p_name, (*it)->numValue());
-      return *it;
-    } else
-      break;
-  }
-  return NULL;
-}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::clean()
-**
-** Description: reset the setting array
-**
-** Returns:     none
-**
-*******************************************************************************/
-void CNfcConfig::clean() {
-  if (size() == 0) return;
-
-  for (iterator it = begin(), itEnd = end(); it != itEnd; ++it) delete *it;
-  clear();
-}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::Add()
-**
-** Description: add a setting object to the list
-**
-** Returns:     none
-**
-*******************************************************************************/
-void CNfcConfig::add(const CNfcParam* pParam) {
-  if (m_list.size() == 0) {
-    m_list.push_back(pParam);
-    return;
-  }
-  for (list<const CNfcParam*>::iterator it = m_list.begin(),
-                                        itEnd = m_list.end();
-       it != itEnd; ++it) {
-    if (**it < pParam->c_str()) continue;
-    m_list.insert(it, pParam);
-    return;
-  }
-  m_list.push_back(pParam);
-}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::moveFromList()
-**
-** Description: move the setting object from list to array
-**
-** Returns:     none
-**
-*******************************************************************************/
-void CNfcConfig::moveFromList() {
-  if (m_list.size() == 0) return;
-
-  for (list<const CNfcParam*>::iterator it = m_list.begin(),
-                                        itEnd = m_list.end();
-       it != itEnd; ++it)
-    push_back(*it);
-  m_list.clear();
-}
-
-/*******************************************************************************
-**
-** Function:    CNfcConfig::moveToList()
-**
-** Description: move the setting object from array to list
-**
-** Returns:     none
-**
-*******************************************************************************/
-void CNfcConfig::moveToList() {
-  if (m_list.size() != 0) m_list.clear();
-
-  for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
-    m_list.push_back(*it);
-  clear();
-}
-
-/*******************************************************************************
-**
-** Function:    CNfcParam::CNfcParam()
-**
-** Description: class constructor
-**
-** Returns:     none
-**
-*******************************************************************************/
-CNfcParam::CNfcParam() : m_numValue(0) {}
-
-/*******************************************************************************
-**
-** Function:    CNfcParam::~CNfcParam()
-**
-** Description: class destructor
-**
-** Returns:     none
-**
-*******************************************************************************/
-CNfcParam::~CNfcParam() {}
-
-/*******************************************************************************
-**
-** Function:    CNfcParam::CNfcParam()
-**
-** Description: class copy constructor
-**
-** Returns:     none
-**
-*******************************************************************************/
-CNfcParam::CNfcParam(const char* name, const string& value)
-    : string(name), m_str_value(value), m_numValue(0) {}
-
-/*******************************************************************************
-**
-** Function:    CNfcParam::CNfcParam()
-**
-** Description: class copy constructor
-**
-** Returns:     none
-**
-*******************************************************************************/
-CNfcParam::CNfcParam(const char* name, unsigned long value)
-    : string(name), m_numValue(value) {}
-
-/*******************************************************************************
-**
-** Function:    GetStrValue
-**
-** Description: API function for getting a string value of a setting
-**
-** Returns:     none
-**
-*******************************************************************************/
-extern int GetStrValue(const char* name, char* pValue, unsigned long l) {
-  size_t len = l;
-  CNfcConfig& rConfig = CNfcConfig::GetInstance();
-
-  bool b = rConfig.getValue(name, pValue, len);
-  return b ? len : 0;
-}
-
-/*******************************************************************************
-**
-** Function:    GetNumValue
-**
-** Description: API function for getting a numerical value of a setting
-**
-** Returns:     none
-**
-*******************************************************************************/
-extern int GetNumValue(const char* name, void* pValue, unsigned long len) {
-  if (!pValue) return false;
-
-  CNfcConfig& rConfig = CNfcConfig::GetInstance();
-  const CNfcParam* pParam = rConfig.find(name);
-
-  if (pParam == NULL) return false;
-  unsigned long v = pParam->numValue();
-  if (v == 0 && pParam->str_len() > 0 && pParam->str_len() < 4) {
-    const unsigned char* p = (const unsigned char*)pParam->str_value();
-    for (size_t i = 0; i < pParam->str_len(); ++i) {
-      v *= 256;
-      v += *p++;
-    }
-  }
-  switch (len) {
-    case sizeof(unsigned long):
-      *(static_cast<unsigned long*>(pValue)) = (unsigned long)v;
-      break;
-    case sizeof(unsigned short):
-      *(static_cast<unsigned short*>(pValue)) = (unsigned short)v;
-      break;
-    case sizeof(unsigned char):
-      *(static_cast<unsigned char*>(pValue)) = (unsigned char)v;
-      break;
-    default:
-      return false;
-  }
-  return true;
-}
-
-/*******************************************************************************
-**
-** Function:    resetConfig
-**
-** Description: reset settings array
-**
-** Returns:     none
-**
-*******************************************************************************/
-extern void resetConfig() {
-  CNfcConfig& rConfig = CNfcConfig::GetInstance();
-
-  rConfig.clean();
-}
-
-/*******************************************************************************
-**
-** Function:    readOptionalConfig()
-**
-** Description: read Config settings from an optional conf file
-**
-** Returns:     none
-**
-*******************************************************************************/
-void readOptionalConfig(const char* extra) {
-  string strPath;
-  string configName(extra_config_base);
-  configName += extra;
-  configName += extra_config_ext;
-
-  findConfigFilePathFromTransportConfigPaths(configName, strPath);
-  CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
-}
diff --git a/src/adaptation/libmain.cc b/src/adaptation/libmain.cc
index a21e183..eb9a9f1 100644
--- a/src/adaptation/libmain.cc
+++ b/src/adaptation/libmain.cc
@@ -18,6 +18,7 @@
 #include <android-base/stringprintf.h>
 #include <base/logging.h>
 #include <fcntl.h>
+#include <vector>
 
 #include "CrcChecksum.h"
 #include "nfa_nv_ci.h"
@@ -25,10 +26,15 @@
 
 using android::base::StringPrintf;
 
-extern char bcm_nfc_location[];
+extern std::string nfc_storage_path;
 extern bool nfc_debug_enabled;
 
-static const char* sNfaStorageBin = "/nfaStorage.bin";
+namespace {
+std::string getFilenameForBlock(const unsigned block) {
+  std::string bin = "nfaStorage.bin";
+  return StringPrintf("%s/%s%u", nfc_storage_path.c_str(), bin.c_str(), block);
+}
+}  // namespace
 
 /*******************************************************************************
 **
@@ -76,21 +82,11 @@
 **
 *******************************************************************************/
 extern void nfa_nv_co_read(uint8_t* pBuffer, uint16_t nbytes, uint8_t block) {
-  char filename[256], filename2[256];
+  std::string filename = getFilenameForBlock(block);
 
-  memset(filename, 0, sizeof(filename));
-  memset(filename2, 0, sizeof(filename2));
-  strcpy(filename2, bcm_nfc_location);
-  strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
-  if (strlen(filename2) > 200) {
-    LOG(ERROR) << StringPrintf("%s: filename too long", __func__);
-    return;
-  }
-  sprintf(filename, "%s%u", filename2, block);
-
-  DLOG_IF(INFO, nfc_debug_enabled)
-      << StringPrintf("%s: buffer len=%u; file=%s", __func__, nbytes, filename);
-  int fileStream = open(filename, O_RDONLY);
+  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
+      "%s: buffer len=%u; file=%s", __func__, nbytes, filename.c_str());
+  int fileStream = open(filename.c_str(), O_RDONLY);
   if (fileStream >= 0) {
     unsigned short checksum = 0;
     read(fileStream, &checksum, sizeof(checksum));
@@ -132,23 +128,13 @@
 *******************************************************************************/
 extern void nfa_nv_co_write(const uint8_t* pBuffer, uint16_t nbytes,
                             uint8_t block) {
-  char filename[256], filename2[256];
+  std::string filename = getFilenameForBlock(block);
 
-  memset(filename, 0, sizeof(filename));
-  memset(filename2, 0, sizeof(filename2));
-  strcpy(filename2, bcm_nfc_location);
-  strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
-  if (strlen(filename2) > 200) {
-    LOG(ERROR) << StringPrintf("%s: filename too long", __func__);
-    return;
-  }
-  sprintf(filename, "%s%u", filename2, block);
-  DLOG_IF(INFO, nfc_debug_enabled)
-      << StringPrintf("%s: bytes=%u; file=%s", __func__, nbytes, filename);
+  DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
+      "%s: bytes=%u; file=%s", __func__, nbytes, filename.c_str());
 
-  int fileStream = 0;
-
-  fileStream = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+  int fileStream =
+      open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
   if (fileStream >= 0) {
     unsigned short checksum = crcChecksumCompute(pBuffer, nbytes);
     size_t actualWrittenCrc = write(fileStream, &checksum, sizeof(checksum));
@@ -182,31 +168,17 @@
 *******************************************************************************/
 void delete_stack_non_volatile_store(bool forceDelete) {
   static bool firstTime = true;
-  char filename[256], filename2[256];
 
   if ((firstTime == false) && (forceDelete == false)) return;
   firstTime = false;
 
   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__);
 
-  memset(filename, 0, sizeof(filename));
-  memset(filename2, 0, sizeof(filename2));
-  strcpy(filename2, bcm_nfc_location);
-  strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
-  if (strlen(filename2) > 200) {
-    LOG(ERROR) << StringPrintf("%s: filename too long", __func__);
-    return;
-  }
-  sprintf(filename, "%s%u", filename2, DH_NV_BLOCK);
-  remove(filename);
-  sprintf(filename, "%s%u", filename2, HC_F3_NV_BLOCK);
-  remove(filename);
-  sprintf(filename, "%s%u", filename2, HC_F4_NV_BLOCK);
-  remove(filename);
-  sprintf(filename, "%s%u", filename2, HC_F2_NV_BLOCK);
-  remove(filename);
-  sprintf(filename, "%s%u", filename2, HC_F5_NV_BLOCK);
-  remove(filename);
+  remove(getFilenameForBlock(DH_NV_BLOCK).c_str());
+  remove(getFilenameForBlock(HC_F2_NV_BLOCK).c_str());
+  remove(getFilenameForBlock(HC_F3_NV_BLOCK).c_str());
+  remove(getFilenameForBlock(HC_F4_NV_BLOCK).c_str());
+  remove(getFilenameForBlock(HC_F5_NV_BLOCK).c_str());
 }
 
 /*******************************************************************************
@@ -222,32 +194,16 @@
 *******************************************************************************/
 void verify_stack_non_volatile_store() {
   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__);
-  char filename[256], filename2[256];
-  bool isValid = false;
 
-  memset(filename, 0, sizeof(filename));
-  memset(filename2, 0, sizeof(filename2));
-  strcpy(filename2, bcm_nfc_location);
-  strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
-  if (strlen(filename2) > 200) {
-    LOG(ERROR) << StringPrintf("%s: filename too long", __func__);
-    return;
+  const std::vector<unsigned> verify_blocks = {DH_NV_BLOCK, HC_F2_NV_BLOCK,
+                                               HC_F3_NV_BLOCK, HC_F4_NV_BLOCK,
+                                               HC_F5_NV_BLOCK};
+
+  size_t verified = 0;
+  for (auto block : verify_blocks) {
+    if (!crcChecksumVerifyIntegrity(getFilenameForBlock(block).c_str())) break;
+    ++verified;
   }
 
-  sprintf(filename, "%s%u", filename2, DH_NV_BLOCK);
-  if (crcChecksumVerifyIntegrity(filename)) {
-    sprintf(filename, "%s%u", filename2, HC_F3_NV_BLOCK);
-    if (crcChecksumVerifyIntegrity(filename)) {
-      sprintf(filename, "%s%u", filename2, HC_F4_NV_BLOCK);
-      if (crcChecksumVerifyIntegrity(filename)) {
-        sprintf(filename, "%s%u", filename2, HC_F2_NV_BLOCK);
-        if (crcChecksumVerifyIntegrity(filename)) {
-          sprintf(filename, "%s%u", filename2, HC_F5_NV_BLOCK);
-          if (crcChecksumVerifyIntegrity(filename)) isValid = true;
-        }
-      }
-    }
-  }
-
-  if (isValid == false) delete_stack_non_volatile_store(true);
+  if (verified != verify_blocks.size()) delete_stack_non_volatile_store(true);
 }
diff --git a/src/include/config.h b/src/include/config.h
deleted file mode 100644
index c1dbf6e..0000000
--- a/src/include/config.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/******************************************************************************
- *
- *  Copyright (C) 1999-2012 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at:
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-int GetStrValue(const char* name, char* p_value, unsigned long len);
-int GetNumValue(const char* name, void* p_value, unsigned long len);
-
-#define NAME_POLLING_TECH_MASK "POLLING_TECH_MASK"
-#define NAME_APPL_TRACE_LEVEL "APPL_TRACE_LEVEL"
-#define NAME_USE_RAW_NCI_TRACE "USE_RAW_NCI_TRACE"
-#define NAME_PROTOCOL_TRACE_LEVEL "PROTOCOL_TRACE_LEVEL"
-#define NAME_NFA_DM_CFG "NFA_DM_CFG"
-#define NAME_SCREEN_OFF_POWER_STATE "SCREEN_OFF_POWER_STATE"
-#define NAME_NFA_STORAGE "NFA_STORAGE"
-#define NAME_UICC_LISTEN_TECH_MASK "UICC_LISTEN_TECH_MASK"
-#define NAME_NFA_DM_DISC_DURATION_POLL "NFA_DM_DISC_DURATION_POLL"
-#define NAME_AID_FOR_EMPTY_SELECT "AID_FOR_EMPTY_SELECT"
-#define NAME_PRESERVE_STORAGE "PRESERVE_STORAGE"
-#define NAME_NFA_MAX_EE_SUPPORTED "NFA_MAX_EE_SUPPORTED"
-#define NAME_POLL_FREQUENCY "POLL_FREQUENCY"
-#define NAME_PRESENCE_CHECK_ALGORITHM "PRESENCE_CHECK_ALGORITHM"
-#define NAME_DEVICE_HOST_WHITE_LIST "DEVICE_HOST_WHITE_LIST"
-#define NAME_NFA_POLL_BAIL_OUT_MODE "NFA_POLL_BAIL_OUT_MODE"
-#define NAME_NFA_PROPRIETARY_CFG "NFA_PROPRIETARY_CFG"
-#define NAME_NFA_AID_BLOCK_ROUTE "NFA_AID_BLOCK_ROUTE"
-#define NAME_ISO_DEP_MAX_TRANSCEIVE "ISO_DEP_MAX_TRANSCEIVE"
-
-#endif
diff --git a/src/nfa/dm/nfa_dm_cfg.cc b/src/nfa/dm/nfa_dm_cfg.cc
index b182ee3..ceef2ff 100644
--- a/src/nfa/dm/nfa_dm_cfg.cc
+++ b/src/nfa/dm/nfa_dm_cfg.cc
@@ -66,7 +66,7 @@
 tNCI_DISCOVER_MAPS* p_nfa_dm_interface_mapping = NULL;
 uint8_t nfa_dm_num_dm_interface_mapping = 0;
 
-const tNFA_DM_CFG nfa_dm_cfg = {
+tNFA_DM_CFG nfa_dm_cfg = {
     /* Automatic NDEF detection (when not in exclusive RF mode) */
     NFA_DM_AUTO_DETECT_NDEF,
     /* Automatic NDEF read (when not in exclusive RF mode) */
@@ -82,7 +82,7 @@
 
 const uint8_t nfa_hci_whitelist[] = {0x02, 0x03, 0x04};
 
-const tNFA_HCI_CFG nfa_hci_cfg = {
+tNFA_HCI_CFG nfa_hci_cfg = {
     /* Max HCI Network IDLE time to wait for EE DISC REQ Ntf(s) */
     NFA_HCI_NETWK_INIT_IDLE_TIMEOUT,
     /* Maximum HCP Response time to any HCP Command */
@@ -95,7 +95,7 @@
 tNFA_HCI_CFG* p_nfa_hci_cfg = (tNFA_HCI_CFG*)&nfa_hci_cfg;
 
 bool nfa_poll_bail_out_mode = false;
-const tNFA_PROPRIETARY_CFG nfa_proprietary_cfg = {
+tNFA_PROPRIETARY_CFG nfa_proprietary_cfg = {
     0x80, /* NCI_PROTOCOL_18092_ACTIVE */
     0x81, /* NCI_PROTOCOL_B_PRIME */
     0x82, /* NCI_PROTOCOL_DUAL */
diff --git a/src/nfa/ee/nfa_ee_main.cc b/src/nfa/ee/nfa_ee_main.cc
index 33befe0..257ec71 100644
--- a/src/nfa/ee/nfa_ee_main.cc
+++ b/src/nfa/ee/nfa_ee_main.cc
@@ -26,9 +26,9 @@
 #include <android-base/stringprintf.h>
 #include <base/logging.h>
 
-#include "config.h"
 #include "nfa_dm_int.h"
 #include "nfa_ee_int.h"
+#include "nfc_config.h"
 
 using android::base::StringPrintf;
 
@@ -117,13 +117,12 @@
 **
 *******************************************************************************/
 void nfa_ee_sys_enable(void) {
-  unsigned long retlen = 0;
-
   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__);
 
   nfa_ee_cb.route_block_control = 0x00;
 
-  if (GetNumValue(NAME_NFA_AID_BLOCK_ROUTE, (void*)&retlen, sizeof(retlen))) {
+  if (NfcConfig::hasKey(NAME_NFA_AID_BLOCK_ROUTE)) {
+    unsigned retlen = NfcConfig::getUnsigned(NAME_NFA_AID_BLOCK_ROUTE);
     if ((retlen == 0x01) && (NFC_GetNCIVersion() == NCI_VERSION_2_0)) {
       nfa_ee_cb.route_block_control = NCI_ROUTE_QUAL_BLOCK_ROUTE;
       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
diff --git a/utils/config.cc b/utils/config.cc
index 36799ae..266bc79 100644
--- a/utils/config.cc
+++ b/utils/config.cc
@@ -133,3 +133,5 @@
 std::vector<uint8_t> ConfigFile::getBytes(const std::string& key) {
   return getValue(key).getBytes();
 }
+
+void ConfigFile::clear() { values_.clear(); }
diff --git a/utils/include/config.h b/utils/include/config.h
index 443abca..90bbcc1 100644
--- a/utils/include/config.h
+++ b/utils/include/config.h
@@ -47,6 +47,8 @@
   unsigned getUnsigned(const std::string& key);
   std::vector<uint8_t> getBytes(const std::string& key);
 
+  void clear();
+
  private:
   ConfigValue& getValue(const std::string& key);
 
diff --git a/utils/include/nfc_config.h b/utils/include/nfc_config.h
index 3476ab3..843d3c2 100644
--- a/utils/include/nfc_config.h
+++ b/utils/include/nfc_config.h
@@ -20,12 +20,34 @@
 
 #include <config.h>
 
+#define NAME_NFC_DEBUG_ENABLED "NFC_DEBUG_ENABLED"
+#define NAME_POLLING_TECH_MASK "POLLING_TECH_MASK"
+#define NAME_NFA_DM_CFG "NFA_DM_CFG"
+#define NAME_SCREEN_OFF_POWER_STATE "SCREEN_OFF_POWER_STATE"
+#define NAME_NFA_STORAGE "NFA_STORAGE"
+#define NAME_UICC_LISTEN_TECH_MASK "UICC_LISTEN_TECH_MASK"
+#define NAME_NFA_DM_DISC_DURATION_POLL "NFA_DM_DISC_DURATION_POLL"
+#define NAME_AID_FOR_EMPTY_SELECT "AID_FOR_EMPTY_SELECT"
+#define NAME_PRESERVE_STORAGE "PRESERVE_STORAGE"
+#define NAME_NFA_MAX_EE_SUPPORTED "NFA_MAX_EE_SUPPORTED"
+#define NAME_POLL_FREQUENCY "POLL_FREQUENCY"
+#define NAME_PRESENCE_CHECK_ALGORITHM "PRESENCE_CHECK_ALGORITHM"
+#define NAME_DEVICE_HOST_WHITE_LIST "DEVICE_HOST_WHITE_LIST"
+#define NAME_NFA_POLL_BAIL_OUT_MODE "NFA_POLL_BAIL_OUT_MODE"
+#define NAME_NFA_PROPRIETARY_CFG "NFA_PROPRIETARY_CFG"
+#define NAME_NFA_AID_BLOCK_ROUTE "NFA_AID_BLOCK_ROUTE"
+#define NAME_ISO_DEP_MAX_TRANSCEIVE "ISO_DEP_MAX_TRANSCEIVE"
+
 class NfcConfig {
  public:
   static bool hasKey(const std::string& key);
   static std::string getString(const std::string& key);
+  static std::string getString(const std::string& key,
+                               std::string default_value);
   static unsigned getUnsigned(const std::string& key);
+  static unsigned getUnsigned(const std::string& key, unsigned default_value);
   static std::vector<uint8_t> getBytes(const std::string& key);
+  static void clear();
 
  private:
   static NfcConfig& getInstance();
diff --git a/utils/nfc_config.cc b/utils/nfc_config.cc
index 0c9f9d2..8476db8 100644
--- a/utils/nfc_config.cc
+++ b/utils/nfc_config.cc
@@ -61,10 +61,24 @@
   return getInstance().config_.getString(key);
 }
 
+std::string NfcConfig::getString(const std::string& key,
+                                 std::string default_value) {
+  if (hasKey(key)) return getString(key);
+  return default_value;
+}
+
 unsigned NfcConfig::getUnsigned(const std::string& key) {
   return getInstance().config_.getUnsigned(key);
 }
 
+unsigned NfcConfig::getUnsigned(const std::string& key,
+                                unsigned default_value) {
+  if (hasKey(key)) return getUnsigned(key);
+  return default_value;
+}
+
 std::vector<uint8_t> NfcConfig::getBytes(const std::string& key) {
   return getInstance().config_.getBytes(key);
 }
+
+void NfcConfig::clear() { getInstance().config_.clear(); }
diff --git a/utils/test/config_test.cc b/utils/test/config_test.cc
index cf3bba5..c31744b 100644
--- a/utils/test/config_test.cc
+++ b/utils/test/config_test.cc
@@ -99,6 +99,17 @@
   EXPECT_DEATH(config5.parseFromString(INVALID_CONFIG5), "");
 }
 
+TEST(ConfigTestFromString, test_clear) {
+  ConfigFile config;
+  EXPECT_FALSE(config.hasKey("NUM_VALUE"));
+  config.parseFromString(SIMPLE_CONFIG);
+  EXPECT_TRUE(config.hasKey("NUM_VALUE"));
+  EXPECT_EQ(config.getUnsigned("NUM_VALUE"), 42u);
+  config.clear();
+  EXPECT_FALSE(config.hasKey("NUM_VALUE"));
+  EXPECT_DEATH(config.getUnsigned("NUM_VALUE"), "");
+}
+
 TEST_F(ConfigTestFromFile, test_file_based_config) {
   ConfigFile config;
   config.parseFromFile(SIMPLE_CONFIG_FILE);