11#include " api_config.h"
22#include " common.h"
33#include " util/cast.hpp"
4- #include " util/inireader.hpp"
54#include " util/strfuns.hpp"
65#include < algorithm>
76#include < cstdlib>
109#include < loguru.hpp>
1110#include < mutex>
1211#include < stdexcept>
12+ #include < sstream>
1313
1414using namespace lsl ;
1515
@@ -52,6 +52,23 @@ bool file_is_readable(const std::string &filename) {
5252}
5353
5454api_config::api_config () {
55+ // first check to see if a config content was provided
56+ if (!api_config_content_.empty ()) {
57+ try {
58+ // if so, load it from the content
59+ load_from_content (api_config_content_);
60+ // free the content this can only be called once
61+ api_config_content_.clear ();
62+ // config loaded successfully, so return
63+ return ;
64+ } catch (std::exception &e) {
65+ LOG_F (ERROR, " Error parsing config content: '%s', rolling back to defaults" , e.what ());
66+ // clear the content, it was invalid anyway
67+ api_config_content_.clear ();
68+ }
69+ }
70+ // otherwise, load the config from a file
71+
5572 // for each config file location under consideration...
5673 std::vector<std::string> filenames;
5774
@@ -92,7 +109,6 @@ api_config::api_config() {
92109 load_from_file ();
93110}
94111
95-
96112void api_config::load_from_file (const std::string &filename) {
97113 try {
98114 INI pt;
@@ -102,7 +118,35 @@ void api_config::load_from_file(const std::string &filename) {
102118 pt.load (infile);
103119 }
104120 }
121+ api_config::load (pt);
122+ // log config filename only after setting the verbosity level and all config has been read
123+ if (!filename.empty ())
124+ LOG_F (INFO, " Configuration loaded from %s" , filename.c_str ());
125+ else
126+ LOG_F (INFO, " Loaded default config" );
127+
128+ } catch (std::exception &e) {
129+ LOG_F (ERROR, " Error parsing config file '%s': '%s', rolling back to defaults" ,
130+ filename.c_str (), e.what ());
131+ // any error: assign defaults
132+ load_from_file ();
133+ // and rethrow
134+ throw e;
135+ }
136+ }
137+
138+ void api_config::load_from_content (const std::string &content) {
139+ // load the content into an INI object
140+ INI pt;
141+ if (!content.empty ()) {
142+ std::istringstream content_stream (content);
143+ pt.load (content_stream);
144+ }
145+ api_config::load (pt);
146+ LOG_F (INFO, " Configuration loaded from content" );
147+ }
105148
149+ void api_config::load (INI &pt) {
106150 // read the [log] settings
107151 int log_level = pt.get (" log.level" , (int )loguru::Verbosity_INFO);
108152 if (log_level < -3 || log_level > 9 )
@@ -274,20 +318,7 @@ void api_config::load_from_file(const std::string &filename) {
274318 smoothing_halftime_ = pt.get (" tuning.SmoothingHalftime" , 90 .0F );
275319 force_default_timestamps_ = pt.get (" tuning.ForceDefaultTimestamps" , false );
276320
277- // log config filename only after setting the verbosity level and all config has been read
278- if (!filename.empty ())
279- LOG_F (INFO, " Configuration loaded from %s" , filename.c_str ());
280- else
281- LOG_F (INFO, " Loaded default config" );
282-
283- } catch (std::exception &e) {
284- LOG_F (ERROR, " Error parsing config file '%s': '%s', rolling back to defaults" ,
285- filename.c_str (), e.what ());
286- // any error: assign defaults
287- load_from_file ();
288- // and rethrow
289- throw e;
290- }
321+
291322}
292323
293324static std::once_flag api_config_once_flag;
0 commit comments