-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
YAML to JsonObject #1808
Comments
Hi @tobozo, For Best regards, |
thanks for your helpful feedback and marvelous documentation 👍 I came up with this recursive function and got a satisfying result, did I miss anything? [edit] pasted the non-leaky version + yaml multiline helper enum JNestingType_t { NONE, SEQ_KEY, MAP_KEY };
#define indent(x) std::string(x*2, ' ').c_str()
// multiline helper
void yaml_multiline_escape_string( Stream* stream, const char* str, size_t length, size_t *bytes_out, size_t depth )
{
size_t i;
char c;
char l = '\0';
String _str = String(str);
bool has_multiline = _str.indexOf('\n') > -1;
if( has_multiline ) *bytes_out += stream->printf("|\n%s", indent(depth) );
for (i = 0; i < length; i++) {
c = *(str + i);
if( c== '\r' || c=='\n' ) {
if( l != '\\' && has_multiline ) { // unescaped \r or \n
if(c == '\r') *bytes_out += 1; // ignore \r
else *bytes_out += stream->printf("\n%s", indent(depth) ); // print CRLF
} else {
if(c == '\n') *bytes_out += stream->printf("\\n");
else *bytes_out += stream->printf("\\r");
}
} else {
if( has_multiline ) {
*bytes_out += stream->printf("%c", c);
} else {
if (c == '\\') *bytes_out += stream->printf("\\\\");
else if (c == '\0') *bytes_out += stream->printf("\\0");
else if (c == '\b') *bytes_out += stream->printf("\\b");
else if (c == '\t') *bytes_out += stream->printf("\\t");
else *bytes_out += stream->printf("%c", c);
}
}
l = c; // memoize last char to spot escaped entities
}
}
// JsonVariant deconstructor => YAML stream
size_t serializeYml_JsonVariant( JsonVariant root, Stream &out, int depth=0, JNestingType_t nt=NONE )
{
int parent_level = depth>0?depth-1:0;
size_t out_size = 0;
if (root.is<JsonArray>()) {
JsonArray array = root;
for( size_t i=0; i<array.size(); i++ ) {
size_t child_depth = array[i].is<JsonObject>() ? depth+1 : depth-1;
out_size += serializeYml_JsonVariant(array[i], out, child_depth, SEQ_KEY);
}
} else if (root.is<JsonObject>()) {
JsonObject object = root;
int i = 0;
for (JsonPair pair : object) {
bool is_seqfirst = (i++==0 && nt==SEQ_KEY);
out_size += out.printf("\n%s%s%s: ", is_seqfirst ? indent(parent_level) : indent(depth), is_seqfirst ? "- " : "", pair.key().c_str() );
out_size += serializeYml_JsonVariant( pair.value(), out, depth+1, MAP_KEY );
}
} else if( !root.isNull() ) {
if( nt == SEQ_KEY ) out_size += out.printf("\n%s%s", indent(depth), "- " );
yaml_multiline_escape_string(&out, root.as<String>().c_str(), root.as<String>().length(), &out_size, depth);
} else {
// Error, root is null
}
return out_size;
} |
Yep, that's the idea. |
Since most data processing softwares bundle their own codecs when exporting to other formats I mostly wrote this function for ArduinoJson (e.g. as an extra example), but just noticed the label change so I guess it's too much out of scope? Please let me know if you want a PR for this, I'll add the function to my esp32-yaml library anyway. thanks again for your support! |
hey @bblanchon and thanks for your awesome library !
Ref.
your answer:
deserializeYaml()
is now implemented: https://github.com/tobozo/esp32-yamlI wish I could produce the
serializeYaml()
andserializeYmlPretty()
for ArduinoJson too but the level of C++ in this library is way beyond my skills.The text was updated successfully, but these errors were encountered: