Render the cstring provided to an escaped version that can be printed. */
| 202 | |
| 203 | /* Render the cstring provided to an escaped version that can be printed. */ |
| 204 | static char *print_string_ptr(const char *str) |
| 205 | { |
| 206 | const char *ptr;char *ptr2,*out;int len=0;unsigned char token; |
| 207 | |
| 208 | if (!str) return cJSON_strdup(""); |
| 209 | ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} |
| 210 | |
| 211 | out=static_cast<char*>(cJSON_malloc(len+3)); |
| 212 | if (!out) return nullptr; |
| 213 | |
| 214 | ptr2=out;ptr=str; |
| 215 | *ptr2++='\"'; |
| 216 | while (*ptr) |
| 217 | { |
| 218 | if (static_cast<unsigned char>(*ptr)>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; |
| 219 | else |
| 220 | { |
| 221 | *ptr2++='\\'; |
| 222 | switch (token=*ptr++) |
| 223 | { |
| 224 | case '\\': *ptr2++='\\'; break; |
| 225 | case '\"': *ptr2++='\"'; break; |
| 226 | case '\b': *ptr2++='b'; break; |
| 227 | case '\f': *ptr2++='f'; break; |
| 228 | case '\n': *ptr2++='n'; break; |
| 229 | case '\r': *ptr2++='r'; break; |
| 230 | case '\t': *ptr2++='t'; break; |
| 231 | default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ |
| 232 | } |
| 233 | } |
| 234 | } |
| 235 | *ptr2++='\"';*ptr2++=0; |
| 236 | return out; |
| 237 | } |
| 238 | /* Invote print_string_ptr (which is useful) on an item. */ |
| 239 | static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);} |
| 240 |
no test coverage detected