-
Notifications
You must be signed in to change notification settings - Fork 6
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
Support quoted relations in collection #633
Changes from all commits
c4ec1de
10eb09e
5330db6
7fc2306
b68cf5a
b53df57
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -245,6 +245,9 @@ int strnput_escape(char **destp, size_t *sizep, size_t pos, | |
Embedded double-quotes are escaped with backslash. At most `size` | ||
characters are written to `dest` (including terminating NUL). | ||
|
||
If `s` is NULL, this function will behave similarly to snprintf(), | ||
except for the added quoting marks. | ||
|
||
Returns number of characters written to `dest` (excluding | ||
terminating NUL). If the output is truncated, the number of | ||
characters which should have been written is returned. | ||
|
@@ -264,24 +267,47 @@ int strnquote(char *dest, size_t size, const char *s, int n, | |
{ | ||
size_t i=0, j=0; | ||
if (!size) dest = NULL; | ||
|
||
/* Write initial quote sign to `dest`. */ | ||
if (!(flags & strquoteNoQuote)) { | ||
if (size > i) dest[i] = '"'; | ||
i++; | ||
} | ||
while (s[j] && (n < 0 || (int)j < n)) { | ||
if (s[j] == '"' && !(flags & strquoteNoEscape)) { | ||
if (size > i) dest[i] = '\\'; | ||
|
||
if (s) { | ||
|
||
/* Loop over each character in source `s` and copy it to `dest`. | ||
If `n` is positive, consume at most `n` characters from `s`. */ | ||
while (s[j] && (n < 0 || (int)j < n)) { | ||
|
||
/* Add backslash (escape) in front of double-quote characters | ||
when copying to `dest` */ | ||
if (s[j] == '"' && !(flags & strquoteNoEscape)) { | ||
if (size > i) dest[i] = '\\'; | ||
i++; | ||
} | ||
if (size > i) dest[i] = s[j]; | ||
i++; | ||
j++; | ||
} | ||
if (size > i) dest[i] = s[j]; | ||
i++; | ||
j++; | ||
|
||
} else { | ||
|
||
/* If `s` is NULL, use system snprintf() to represent it in a standard | ||
way. */ | ||
int m = snprintf(dest+i, PDIFF(size, i), "%s", s); | ||
if (m >= 0) i += j; | ||
} | ||
|
||
/* Write final quote sign to `dest`. */ | ||
if (!(flags & strquoteNoQuote)) { | ||
if (dest && size > i) dest[i] = '"'; | ||
i++; | ||
} | ||
|
||
/* Ensure that `dest` is NUL-terminated. */ | ||
if (dest) dest[(size > i) ? i : size-1] = '\0'; | ||
|
||
return i; | ||
} | ||
|
||
|
@@ -313,7 +339,7 @@ int strunquote(char *dest, size_t size, const char *s, | |
|
||
|
||
/* | ||
Like strunquote, but if `n` is non-negative, at most `n` bytes are | ||
Like strunquote(), but if `n` is non-negative, at most `n` bytes are | ||
read from `s`. | ||
|
||
This mostly make sense in combination when `flags & strquoteNoEscape` | ||
|
@@ -342,6 +368,42 @@ int strnunquote(char *dest, size_t size, const char *s, int n, | |
} | ||
|
||
|
||
/* | ||
Like strnunquote(), but reallocates the destination and writes to | ||
position `pos`. | ||
|
||
On allocation error, -3 is returned. | ||
*/ | ||
int strnput_unquote(char **destp, size_t *sizep, size_t pos, const char *s, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hard to follow logic. Please document what is the execution logic, or use a standard function to simplify the expression There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good suggestion. When adding explanations it became clear that the code both could be simplified and made more efficient by removing an unnecessary call to realloc(). |
||
int n, int *consumed, StrquoteFlags flags) | ||
{ | ||
int m; | ||
/* Ensure consistency */ | ||
if (!*destp) *sizep = 0; | ||
if (!*sizep) *destp = NULL; | ||
|
||
/* Use strnunquote() to get now much memory we need. */ | ||
m = strnunquote(NULL, 0, s, n, consumed, flags); | ||
if (m < 0) return m; // On error, pass it on... | ||
|
||
/* If the allocated size is not large enough, reallocate `*destp` to the | ||
needed size. */ | ||
if (m + pos >= *sizep) { | ||
char *q; | ||
size_t size = m + pos + 1; | ||
if (!(q = realloc(*destp, size))) return -3; | ||
*destp = q; | ||
*sizep = size; | ||
} | ||
|
||
/* Use strnunquote() again to write the allocated buffer. */ | ||
m = strnunquote(*destp+pos, PDIFF(*sizep, pos), s, n, consumed, flags); | ||
assert(m >= 0); // we don't expect any errors now | ||
assert(m + pos < *sizep); // the buffer should be large enough | ||
return m; | ||
} | ||
|
||
|
||
/******************************************************************** | ||
* Hexadecimal encoding/decoding | ||
********************************************************************/ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hard to follow the logic. Comment line-by-line what is happening here, or simplify the expression with standard functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments to make it easier to follow.