384 result.ptr[result.length] = 0; |
384 result.ptr[result.length] = 0; |
385 |
385 |
386 return result; |
386 return result; |
387 } |
387 } |
388 |
388 |
389 static cxmutstr escape_string(cxmutstr str) { |
389 static cxmutstr escape_string(cxmutstr str, bool escape_slash) { |
390 // note: this function produces the string without enclosing quotes |
390 // note: this function produces the string without enclosing quotes |
391 // the reason is that we don't want to allocate memory just for that |
391 // the reason is that we don't want to allocate memory just for that |
392 CxBuffer buf = {0}; |
392 CxBuffer buf = {0}; |
393 |
393 |
394 bool all_printable = true; |
394 bool all_printable = true; |
395 for (size_t i = 0; i < str.length; i++) { |
395 for (size_t i = 0; i < str.length; i++) { |
396 bool escape = !isprint(str.ptr[i]) |
396 bool escape = !isprint(str.ptr[i]) |
397 || str.ptr[i] == '\\' |
397 || str.ptr[i] == '\\' |
398 || str.ptr[i] == '"' |
398 || str.ptr[i] == '"' |
399 // TODO: make escaping slash optional |
399 || (escape_slash && str.ptr[i] == '/'); |
400 || str.ptr[i] == '/'; |
|
401 |
400 |
402 if (all_printable && escape) { |
401 if (all_printable && escape) { |
403 size_t capa = str.length + 32; |
402 size_t capa = str.length + 32; |
404 char *space = malloc(capa); |
403 char *space = malloc(capa); |
405 if (space == NULL) return cx_mutstrn(NULL, 0); |
404 if (space == NULL) return cx_mutstrn(NULL, 0); |
1147 } |
1148 } |
1148 } |
1149 } |
1149 |
1150 |
1150 // the name |
1151 // the name |
1151 actual += wfunc("\"", 1, 1, target); |
1152 actual += wfunc("\"", 1, 1, target); |
1152 cxmutstr name = escape_string(member->name); |
1153 cxmutstr name = escape_string(member->name, settings->escape_slash); |
1153 actual += wfunc(name.ptr, 1, name.length, target); |
1154 actual += wfunc(name.ptr, 1, name.length, target); |
1154 if (name.ptr != member->name.ptr) { |
1155 if (name.ptr != member->name.ptr) { |
1155 cx_strfree(&name); |
1156 cx_strfree(&name); |
1156 } |
1157 } |
1157 actual += wfunc("\"", 1, 1, target); |
1158 actual += wfunc("\"", 1, 1, target); |
1217 expected++; |
1218 expected++; |
1218 break; |
1219 break; |
1219 } |
1220 } |
1220 case CX_JSON_STRING: { |
1221 case CX_JSON_STRING: { |
1221 actual += wfunc("\"", 1, 1, target); |
1222 actual += wfunc("\"", 1, 1, target); |
1222 cxmutstr str = escape_string(value->value.string); |
1223 cxmutstr str = escape_string(value->value.string, settings->escape_slash); |
1223 actual += wfunc(str.ptr, 1, str.length, target); |
1224 actual += wfunc(str.ptr, 1, str.length, target); |
1224 if (str.ptr != value->value.string.ptr) { |
1225 if (str.ptr != value->value.string.ptr) { |
1225 cx_strfree(&str); |
1226 cx_strfree(&str); |
1226 } |
1227 } |
1227 actual += wfunc("\"", 1, 1, target); |
1228 actual += wfunc("\"", 1, 1, target); |