summaryrefslogtreecommitdiff
path: root/src/cursor
diff options
context:
space:
mode:
authorAlex Gorrod <alexander.gorrod@mongodb.com>2016-06-01 12:38:19 +1000
committerAlex Gorrod <alexander.gorrod@mongodb.com>2016-06-01 12:38:19 +1000
commitff108d7c705b82e482fb17e33488dc14304bf259 (patch)
tree6cdc57dd2b037f9f61848ba1eae74c214b406e6a /src/cursor
parent6f9a7a41f21476235b0bb99f0f16a2d7f738c2e0 (diff)
parent7033ed47f3986edb08ec8c4933e6ef211e73b3c4 (diff)
downloadmongo-ff108d7c705b82e482fb17e33488dc14304bf259.tar.gz
Merge branch 'develop' into mongodb-3.4
Diffstat (limited to 'src/cursor')
-rw-r--r--src/cursor/cur_dump.c21
-rw-r--r--src/cursor/cur_json.c98
2 files changed, 66 insertions, 53 deletions
diff --git a/src/cursor/cur_dump.c b/src/cursor/cur_dump.c
index a7b1c98871a..32353e0a28d 100644
--- a/src/cursor/cur_dump.c
+++ b/src/cursor/cur_dump.c
@@ -155,7 +155,9 @@ __curdump_set_key(WT_CURSOR *cursor, ...)
WT_SESSION_IMPL *session;
uint64_t recno;
va_list ap;
+ const uint8_t *up;
const char *p;
+ bool json;
cdump = (WT_CURSOR_DUMP *)cursor;
child = cdump->child;
@@ -168,16 +170,23 @@ __curdump_set_key(WT_CURSOR *cursor, ...)
p = va_arg(ap, const char *);
va_end(ap);
+ json = F_ISSET(cursor, WT_CURSTD_DUMP_JSON);
+ if (json)
+ WT_ERR(__wt_json_to_item(session, p, cursor->key_format,
+ (WT_CURSOR_JSON *)cursor->json_private, true,
+ &cursor->key));
+
if (WT_CURSOR_RECNO(cursor) && !F_ISSET(cursor, WT_CURSTD_RAW)) {
- WT_ERR(str2recno(session, p, &recno));
+ if (json) {
+ up = (const uint8_t *)cursor->key.data;
+ WT_ERR(__wt_vunpack_uint(&up, cursor->key.size,
+ &recno));
+ } else
+ WT_ERR(str2recno(session, p, &recno));
child->set_key(child, recno);
} else {
- if (F_ISSET(cursor, WT_CURSTD_DUMP_JSON))
- WT_ERR(__wt_json_to_item(session, p, cursor->key_format,
- (WT_CURSOR_JSON *)cursor->json_private, true,
- &cursor->key));
- else
+ if (!json)
WT_ERR(__dump_to_raw(session, p, &cursor->key,
F_ISSET(cursor, WT_CURSTD_DUMP_HEX)));
diff --git a/src/cursor/cur_json.c b/src/cursor/cur_json.c
index fcb66d3e8b3..133b7b9ac9b 100644
--- a/src/cursor/cur_json.c
+++ b/src/cursor/cur_json.c
@@ -48,6 +48,10 @@ static int __json_pack_size(WT_SESSION_IMPL *, const char *, WT_CONFIG_ITEM *,
case 't': \
WT_RET(json_uint_arg(session, &jstr, &pv.u.u)); \
break; \
+ case 'u': \
+ WT_RET(json_string_arg(session, &jstr, &pv.u.item)); \
+ pv.type = 'K'; \
+ break; \
/* User format strings have already been validated. */ \
WT_ILLEGAL_VALUE(session); \
} \
@@ -493,7 +497,7 @@ __wt_json_token(WT_SESSION *wt_session, const char *src, int *toktype,
"invalid Unicode within JSON string");
return (-1);
}
- src += 5;
+ src += 4;
}
backslash = false;
}
@@ -840,20 +844,17 @@ __wt_json_strlen(const char *src, size_t srclen)
if (__wt_hex2byte((const u_char *)src, &lo))
return (-1);
src += 2;
- /* RFC 3629 */
- if (hi >= 0x8) {
- /* 3 bytes total */
- dstlen += 2;
- }
- else if (hi != 0 || lo >= 0x80) {
- /* 2 bytes total */
- dstlen++;
- }
- /* else 1 byte total */
+ if (hi != 0)
+ /*
+ * For our dump representation,
+ * every Unicode character on input
+ * represents a single byte.
+ */
+ return (-1);
}
- }
+ } else
+ src++;
dstlen++;
- src++;
}
if (src != srcend)
return (-1); /* invalid input, e.g. final char is '\\' */
@@ -867,55 +868,58 @@ __wt_json_strlen(const char *src, size_t srclen)
* the result if zero padded.
*/
int
-__wt_json_strncpy(char **pdst, size_t dstlen, const char *src, size_t srclen)
+__wt_json_strncpy(WT_SESSION *wt_session, char **pdst, size_t dstlen,
+ const char *src, size_t srclen)
{
- char *dst;
+ WT_SESSION_IMPL *session;
+ char ch, *dst;
const char *dstend, *srcend;
u_char hi, lo;
+ session = (WT_SESSION_IMPL *)wt_session;
+
dst = *pdst;
dstend = dst + dstlen;
srcend = src + srclen;
while (src < srcend && dst < dstend) {
/* JSON can include any UTF-8 expressed in 4 hex chars. */
- if (*src == '\\') {
- if (*++src == 'u') {
- if (__wt_hex2byte((const u_char *)++src, &hi))
+ if ((ch = *src++) == '\\')
+ switch (ch = *src++) {
+ case 'u':
+ if (__wt_hex2byte((const u_char *)src, &hi))
return (EINVAL);
src += 2;
if (__wt_hex2byte((const u_char *)src, &lo))
return (EINVAL);
src += 2;
- /* RFC 3629 */
- if (hi >= 0x8) {
- /* 3 bytes total */
- /* byte 0: 1110HHHH */
- /* byte 1: 10HHHHLL */
- /* byte 2: 10LLLLLL */
- *dst++ = (char)(0xe0 |
- ((hi >> 4) & 0x0f));
- *dst++ = (char)(0x80 |
- ((hi << 2) & 0x3c) |
- ((lo >> 6) & 0x03));
- *dst++ = (char)(0x80 | (lo & 0x3f));
- } else if (hi != 0 || lo >= 0x80) {
- /* 2 bytes total */
- /* byte 0: 110HHHLL */
- /* byte 1: 10LLLLLL */
- *dst++ = (char)(0xc0 |
- (hi << 2) |
- ((lo >> 6) & 0x03));
- *dst++ = (char)(0x80 | (lo & 0x3f));
- } else
- /* else 1 byte total */
- /* byte 0: 0LLLLLLL */
- *dst++ = (char)lo;
+ if (hi != 0) {
+ __wt_errx(NULL, "Unicode \"%6.6s\""
+ " byte out of range in JSON",
+ src - 6);
+ return (EINVAL);
+ }
+ *dst++ = (char)lo;
+ break;
+ case 'f':
+ *dst++ = '\f';
+ break;
+ case 'n':
+ *dst++ = '\n';
+ break;
+ case 'r':
+ *dst++ = '\r';
+ break;
+ case 't':
+ *dst++ = '\t';
+ break;
+ case '"':
+ case '\\':
+ *dst++ = ch;
+ break;
+ WT_ILLEGAL_VALUE(session);
}
- else
- *dst++ = *src;
- } else
- *dst++ = *src;
- src++;
+ else
+ *dst++ = ch;
}
if (src != srcend)
return (ENOMEM);