Skip to content

Commit

Permalink
Merged changes from netmail to allow disabling of escaping invalid ch…
Browse files Browse the repository at this point in the history
…aracters, and to add WJWOpenMemDocument
  • Loading branch information
Micah N Gorrell committed Sep 12, 2016
1 parent 6592230 commit 59bdbdc
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 10 deletions.
19 changes: 19 additions & 0 deletions include/wjwriter.h
Expand Up @@ -42,6 +42,19 @@ typedef struct {
*/
int base;

/*
If set to TRUE (enabled by default) then any character that can not be
encoded as a UTF8 character will be written as \xXX where XX are a hex
representation of the value.
This can be disabled since it is non-standard JSON and will cause parse
errors with some parsers.
If disabled then any invalid characters will not be written to the
document.
*/
XplBool escapeInvalidChars;

struct {
void *data;
WJWriteCallback cb;
Expand Down Expand Up @@ -115,6 +128,12 @@ EXPORT XplBool WJWRawValue(char *name, char *value, XplBool done, WJWriter doc
EXPORT size_t WJWFileCallback(char *buffer, size_t length, void *data);
#define WJWOpenFILEDocument(pretty, file) _WJWOpenDocument((pretty), WJWFileCallback, (file), 0)

/*
An alternative method of opening a JSON document for writing, which will
provide a proper callback for allocating and writing to a memory allocation.
*/
EXPORT WJWriter WJWOpenMemDocument(XplBool pretty, char **mem);

#ifdef __cplusplus
}
#endif
Expand Down
58 changes: 48 additions & 10 deletions src/wjwriter/wjwriter.c
Expand Up @@ -267,10 +267,11 @@ EXPORT WJWriter _WJWOpenDocument(XplBool pretty, WJWriteCallback callback, void
The first value after opening a document should not be preceded by a
comma. skipcomma will be reset after reading that first value.
*/
doc->public.pretty = pretty;
doc->public.base = 10;
doc->skipcomma = TRUE;
doc->skipbreak = TRUE;
doc->public.pretty = pretty;
doc->public.escapeInvalidChars = TRUE;
doc->public.base = 10;
doc->skipcomma = TRUE;
doc->skipbreak = TRUE;

return((WJWriter) doc);
}
Expand Down Expand Up @@ -336,6 +337,39 @@ EXPORT size_t WJWFileCallback(char *buffer, size_t length, void *data)
return(0);
}

static size_t WJWMemCallback(char *buffer, size_t length, void *data)
{
char **mem = data;
size_t l;

if (mem) {
if (!*mem) {
*mem = MemMallocWait(length + 1);
memcpy(*mem, buffer, length);
(*mem)[length] = '\0';
} else {
l = strlen(*mem);

*mem = MemReallocWait(*mem, l + length + 1);
memcpy(*mem + l, buffer, length);
(*mem)[l + length] = '\0';
}

return(length);
}

return(0);
}

EXPORT WJWriter WJWOpenMemDocument(XplBool pretty, char **mem)
{
if (!mem) {
return(NULL);
}

return(_WJWOpenDocument(pretty, WJWMemCallback, mem, 0));
}

/*
Verify that str points to a valid UTF8 character, and return the length of
that character in bytes. If the value is not a full valid UTF8 character
Expand Down Expand Up @@ -440,8 +474,9 @@ static XplBool WJWriteString(char *value, size_t length, XplBool done, WJIWriter
e += (l - 1);
} else if (l == 1) {
/*
*e is valid UTF8 but is not a printable character, and will be escaped before
being sent, using the JSON-standard "\u00xx" form
*e is valid UTF8 but is not a printable character, and
will be escaped before being sent, using the
JSON-standard "\u00xx" form
*/
char unicodeHex[sizeof("\\u0000")];

Expand All @@ -454,15 +489,18 @@ static XplBool WJWriteString(char *value, size_t length, XplBool done, WJIWriter
} else if (l < 0) {
/*
*e is not valid UTF8 data, and must be escaped before
being sent. But JSON-standard does not give us a mechanism
so we chose "\xhh" format because of its almost universal comprehension.
being sent. But JSON-standard does not give us a
mechanism so we chose "\xhh" format because of its
almost universal comprehension.
*/
char nonUnicodeHex[sizeof("\\x00")];

WJWrite(doc, v, e - v);

sprintf(nonUnicodeHex, "\\x%02x", (unsigned char) *e);
WJWrite(doc, nonUnicodeHex, sizeof(nonUnicodeHex)-1);
if (doc->public.escapeInvalidChars) {
sprintf(nonUnicodeHex, "\\x%02x", (unsigned char) *e);
WJWrite(doc, nonUnicodeHex, sizeof(nonUnicodeHex)-1);
}

v = e + 1;
}
Expand Down

0 comments on commit 59bdbdc

Please sign in to comment.