25 #ifndef __RSJPARSE_HPP__ 26 #define __RSJPARSE_HPP__ 32 #include <unordered_map> 80 if (str.empty())
return(str);
81 if (max_count<0) max_count = str.length();
85 for (p=0; p<max_count; ++p)
86 if (chars.find(str[p])==std::string::npos)
break;
91 int q, strlenm1=str.length()-1;
92 for (q=0; q<max_count; ++q)
93 if (chars.find(str[strlenm1-q])==std::string::npos)
break;
94 str.erase (str.length()-q, q);
104 std::string ret =
strtrim (str,
"\"");
107 if (qq && ret!=str) *qq =
'\'';
118 int is_bracket (
char c, std::vector<char const*>& bracks,
int indx=0) {
119 for (
unsigned int b = 0; b < bracks.size(); ++b)
120 if (c==bracks[b][indx])
128 std::vector<std::string> ret;
131 std::vector<int> bracket_stack;
132 std::vector<int> quote_stack;
133 bool escape_active =
false;
136 for (
unsigned int a = 0; a < str.length(); ++a) {
139 if ( bracket_stack.size()==0 && quote_stack.size()==0 && str[a]==
RSJarraydelimiter ) {
140 ret.push_back (current);
141 current.clear(); bracket_stack.clear(); quote_stack.clear(); escape_active =
false;
148 if (quote_stack.size() > 0) {
150 escape_active = !escape_active;
151 else if (!escape_active && str[a]==RSJstringquotes[quote_stack.back()][1] ) {
152 quote_stack.pop_back();
153 escape_active =
false;
156 escape_active =
false;
158 current.push_back (str[a]);
162 if (quote_stack.size()==0) {
163 if ((bi =
is_bracket (str[a], RSJstringquotes)) >= 0) {
164 quote_stack.push_back (bi);
165 current.push_back (str[a]);
173 if (quote_stack.size()==0) {
178 size_t newline_pos = str.find (
"\n", a);
179 if (newline_pos == std::string::npos)
180 newline_pos = str.find (
"\r", a);
182 if (newline_pos != std::string::npos)
193 if ( bracket_stack.size()>0 && str[a]==RSJbrackets[bracket_stack.back()][1] ) {
194 bracket_stack.pop_back();
195 current.push_back (str[a]);
199 if ((bi =
is_bracket (str[a], RSJbrackets)) >= 0) {
200 bracket_stack.push_back (bi);
201 current.push_back (str[a]);
207 current.push_back (str[a]);
210 if (current.length() > 0)
211 ret.push_back (current);
218 for (
unsigned int a=0; a < str.length(); ++a)
234 typedef std::unordered_map <std::string,RSJresource>
RSJobject;
255 RSJresource (std::string str) : data (str), _exists (true), parsed_data_p (NULL) { }
259 template <
class dataType>
263 RSJresource (std::istream& is) : _exists (true), parsed_data_p (NULL) {
264 data = std::string ( (std::istreambuf_iterator<char>(is)), (std::istreambuf_iterator<char>()) );
266 RSJresource (std::ifstream& ifs) : _exists (true), parsed_data_p (NULL) {
267 std::istream& is = ifs;
268 data = std::string ( (std::istreambuf_iterator<char>(is)), (std::istreambuf_iterator<char>()) );
281 void parse_full (
bool force=
false,
int max_depth=INT_MAX,
int* parse_count_for_verbose_p=NULL);
283 void fast_parse (std::string* str_p=NULL,
bool copy_string=
false,
int max_depth=INT_MAX,
size_t* parse_start_str_pos=NULL);
297 std::string
as_str (
bool print_comments=
false,
bool update_data=
true);
298 void print (
bool print_comments=
false,
bool update_data=
true)
299 { std::cout <<
as_str(print_comments,update_data) << std::endl; }
308 template <
class dataType>
309 dataType
as (
const dataType& def = dataType()) {
310 if (!
exists())
return (def);
311 return dataType (data);
315 template <
class dataType,
class vectorType=std::vector<dataType> >
316 vectorType
as_vector (
const vectorType& def = vectorType());
319 template <
class dataType,
class mapType=std::unordered_map<std::
string,dataType> >
320 mapType
as_map (
const mapType& def = mapType());
335 std::string content =
strtrim(data);
340 if (content.length() != data.length()) {
342 for (
unsigned int a=0; a<nvPairs.size(); ++a) {
344 object.insert (make_pair(
349 if (
object.
size() > 0) {
359 if (content.length() != data.length()) {
361 for (
unsigned int a=0; a<nvPairs.size(); ++a)
363 if (array.size() > 0) {
382 for (
auto it=
object.begin(); it!=
object.end(); ++it)
383 if (!(it->second.exists())) {
389 return (
object.
size());
393 while (!(array[array.size()-1].exists()))
395 return (array.size());
405 int size(
void) {
return (cleanup()); }
420 else parsed_data_p = NULL;
427 else parsed_data_p = NULL;
433 return (parsed_data_p->
size());
439 return (parsed_data_p->
type);
450 for (
auto it=parsed_data_p->
object.begin(); it!=parsed_data_p->
object.end(); ++it) {
452 if (std::next(it) != parsed_data_p->
object.end()) ret +=
",";
454 ret +=
" // " +
to_string(it->second.type());
461 for (
auto it=parsed_data_p->
array.begin(); it!=parsed_data_p->
array.end(); ++it) {
463 if (std::next(it) != parsed_data_p->
array.end()) ret +=
",";
473 if (update_data) data = ret;
485 return (parsed_data_p->
type);
489 if (max_depth==0)
return;
493 if (parse_count_for_verbose_p) {
494 (*parse_count_for_verbose_p)++;
495 if ( (*parse_count_for_verbose_p) % 100 == 0)
496 std::cout <<
"parse_full: " << (*parse_count_for_verbose_p) <<
" calls." << std::endl;
500 for (
auto it=parsed_data_p->
object.begin(); it!=parsed_data_p->
object.end(); ++it)
501 it->second.parse_full (force, max_depth-1, parse_count_for_verbose_p);
503 for (
auto it=parsed_data_p->
array.begin(); it!=parsed_data_p->
array.end(); ++it)
504 it->parse_full (force, max_depth-1, parse_count_for_verbose_p);
512 int seek_next (std::string* str_p,
int start_pos,
char character) {
527 std::string& str = *str_p;
533 std::vector<int> bracket_stack;
534 std::vector<int> quote_stack;
535 bool escape_active =
false;
538 bool initial_whitespaces =
true;
541 if (!parse_start_str_pos) {
542 parse_start_str_pos =
new size_t;
543 *parse_start_str_pos = 0;
547 size_t a = *parse_start_str_pos;
549 while (*parse_start_str_pos < str_p->length()) {
552 if (initial_whitespaces) {
553 if (str[a] ==
' ' || str[a] ==
'\n' || str[a] ==
'\r' || str[a] ==
'\t' ) {
561 initial_whitespaces =
false;
567 if ( bracket_stack.size()==0 && quote_stack.size()==0 && str[a]==
RSJarraydelimiter ) {
571 bracket_stack.clear(); quote_stack.clear(); escape_active =
false;
578 if (quote_stack.size() > 0) {
580 escape_active = !escape_active;
581 else if (!escape_active && str[a]==RSJstringquotes[quote_stack.back()][1] ) {
582 quote_stack.pop_back();
583 escape_active =
false;
586 escape_active =
false;
592 if (quote_stack.size()==0) {
593 if ((bi =
is_bracket (str[a], RSJstringquotes)) >= 0) {
594 quote_stack.push_back (bi);
603 if (quote_stack.size()==0) {
608 size_t newline_pos = str.find (
"\n", a);
609 if (newline_pos == std::string::npos)
610 newline_pos = str.find (
"\r", a);
612 if (newline_pos != std::string::npos)
623 if ( bracket_stack.size()>0 && str[a]==RSJbrackets[bracket_stack.back()][1] ) {
624 bracket_stack.pop_back();
629 if ((bi =
is_bracket (str[a], RSJbrackets)) >= 0) {
630 bracket_stack.push_back (bi);
644 delete parse_start_str_pos;
656 return (parsed_data_p->
object);
667 return (parsed_data_p->
array);
672 if (indx >= parsed_data_p->
array.size())
673 parsed_data_p->
array.resize(indx+1);
674 return (parsed_data_p->
array[indx]);
681 template <
class dataType,
class vectorType>
683 if (!
exists())
return (def);
686 for (
auto it=parsed_data_p->
array.begin(); it!=parsed_data_p->
array.end(); ++it)
687 ret.push_back (it->as<dataType>());
691 template <
class dataType,
class mapType>
693 if (!
exists())
return (def);
696 for (
auto it=parsed_data_p->
object.begin(); it!=parsed_data_p->
object.end(); ++it)
697 ret[it->first] = it->second.as<dataType>();
705 #define rsjObject as<RSJobject>() 706 #define rsjArray as<RSJarray>() 707 #define rsjAs(t) as<t>() 713 if (!
exists())
return (def);
720 if (!
exists())
return (def);
729 std::string RSJresource::as<std::string> (
const std::string& def) {
730 if (!
exists())
return (def);
735 std::vector< std::vector<std::string> > escapes = { {
"\\n",
"\n"}, {
"\\r",
"\r"}, {
"\\t",
"\t"}, {
"\\\\",
"\\"} };
737 escapes.push_back ({
"\\\"",
"\""});
739 escapes.push_back ({
"\\'",
"'"});
741 for (
unsigned int a=0; a < escapes.size(); ++a)
742 for ( std::size_t start_pos=ret.find(escapes[a][0]); start_pos!=std::string::npos; start_pos=ret.find(escapes[a][0],start_pos) ) {
743 ret.replace (start_pos, escapes[a][0].length(), escapes[a][1]);
744 start_pos += escapes[a][1].length();
752 int RSJresource::as<int> (
const int& def) {
753 if (!
exists())
return (def);
759 double RSJresource::as<double> (
const double& def) {
760 if (!
exists())
return (def);
766 bool RSJresource::as<bool> (
const bool& def) {
767 if (!
exists())
return (def);
769 if (cleanData==
"true" || cleanData==
"TRUE" || cleanData==
"True" || atoi(cleanData.c_str())!=0)
return (
true);
std::vector< std::string > split_RSJ_array(const std::string &str)
Definition: RSJparser.hpp:126
RSJobject & as_object(bool force=false)
Definition: RSJparser.hpp:653
vectorType as_vector(const vectorType &def=vectorType())
Definition: RSJparser.hpp:682
int size(void)
Definition: RSJparser.hpp:405
RSJparsedData()
Definition: RSJparser.hpp:331
static std::string RSJlinecommentstart
Definition: RSJparser.hpp:55
mapType as_map(const mapType &def=mapType())
Definition: RSJparser.hpp:692
static char RSJobjectassignment
Definition: RSJparser.hpp:49
bool exists(void)
Definition: RSJparser.hpp:293
RSJresourceType
Definition: RSJparser.hpp:59
RSJresourceType type(void)
Definition: RSJparser.hpp:436
std::string data
Definition: RSJparser.hpp:245
Definition: RSJparser.hpp:59
RSJresource(dataType d)
Definition: RSJparser.hpp:260
Definition: RSJparser.hpp:59
Definition: RSJparser.hpp:76
Definition: RSJparser.hpp:59
std::string as_str(bool print_comments=false, bool update_data=true)
Definition: RSJparser.hpp:442
RSJresource(std::istream &is)
Definition: RSJparser.hpp:263
RSJresourceType type
Definition: RSJparser.hpp:330
RSJresource & operator=(const RSJresource &r)
Definition: RSJparser.hpp:423
RSJarray & as_array(bool force=false)
Definition: RSJparser.hpp:664
static std::vector< char const * > RSJbrackets
Definition: RSJparser.hpp:52
static char RSJarraydelimiter
Definition: RSJparser.hpp:50
std::vector< RSJresource > RSJarray
Definition: RSJparser.hpp:235
int seek_next(std::string *str_p, int start_pos, char character)
Definition: RSJparser.hpp:512
std::string & raw_data(void)
Definition: RSJparser.hpp:292
Definition: RSJparser.hpp:59
static std::vector< char const * > RSJstringquotes
Definition: RSJparser.hpp:53
static std::string RSJprinttab
Definition: RSJparser.hpp:57
int size(void)
Definition: RSJparser.hpp:431
RSJresourceType parse(bool force=false)
Definition: RSJparser.hpp:482
bool _exists
Definition: RSJparser.hpp:246
Definition: RSJparser.hpp:240
int cleanup(void)
Definition: RSJparser.hpp:376
bool is_parsed(void)
Definition: RSJparser.hpp:294
RSJobject object
Definition: RSJparser.hpp:327
dataType as(const dataType &def=dataType())
Definition: RSJparser.hpp:309
std::string strtrim(std::string str, std::string chars=" \\, int max_count=-1, StrTrimDir dirs=STRTRIM_LR)
Definition: RSJparser.hpp:79
std::string to_string(RSJresourceType rt)
Definition: RSJparser.hpp:65
std::string strip_outer_quotes(std::string str, char *qq=NULL)
Definition: RSJparser.hpp:101
int is_bracket(char c, std::vector< char const *> &bracks, int indx=0)
Definition: RSJparser.hpp:118
RSJresource(std::string str)
Definition: RSJparser.hpp:255
std::string insert_tab_after_newlines(std::string str)
Definition: RSJparser.hpp:217
StrTrimDir
Definition: RSJparser.hpp:76
RSJresource()
Definition: RSJparser.hpp:253
~RSJresource()
Definition: RSJparser.hpp:412
std::unordered_map< std::string, RSJresource > RSJobject
Definition: RSJparser.hpp:231
RSJparsedData * parsed_data_p
Definition: RSJparser.hpp:249
static char RSJcharescape
Definition: RSJparser.hpp:54
static char const * RSJarraybrackets
Definition: RSJparser.hpp:48
void parse_full(bool force=false, int max_depth=INT_MAX, int *parse_count_for_verbose_p=NULL)
Definition: RSJparser.hpp:488
Definition: RSJparser.hpp:76
RSJresource & operator[](std::string key)
Definition: RSJparser.hpp:659
Definition: RSJparser.hpp:325
static char const * RSJobjectbrackets
Definition: RSJparser.hpp:47
RSJarray array
Definition: RSJparser.hpp:328
void fast_parse(std::string *str_p=NULL, bool copy_string=false, int max_depth=INT_MAX, size_t *parse_start_str_pos=NULL)
Definition: RSJparser.hpp:520
RSJresource(std::ifstream &ifs)
Definition: RSJparser.hpp:266
void print(bool print_comments=false, bool update_data=true)
Definition: RSJparser.hpp:298
Definition: RSJparser.hpp:59
Definition: RSJparser.hpp:76
void parse(const std::string &data, RSJresourceType typ=RSJ_UNKNOWN)
Definition: RSJparser.hpp:334
RSJresource(const char *str)
Definition: RSJparser.hpp:256