diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-03-11 10:46:05 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-03-11 10:46:05 +1100 |
commit | 405f6a3969536ae378a343b3387a433236e85d37 (patch) | |
tree | 26fa42ce7bd0aa59000addcd047acf0fe28d1ad6 | |
parent | a3de55629620c7dd9e51971f3f4201bd60acad8a (diff) | |
download | mongo-405f6a3969536ae378a343b3387a433236e85d37.tar.gz |
Layer dump cursors on top of any cursor type.
--HG--
extra : rebase_source : a0ddaa6ba4d7ed5fdb7ca8811f2147e3ede0bad3
-rw-r--r-- | src/cursor/cur_config.c | 3 | ||||
-rw-r--r-- | src/cursor/cur_dump.c | 187 | ||||
-rw-r--r-- | src/cursor/cur_file.c | 3 | ||||
-rw-r--r-- | src/cursor/cur_index.c | 4 | ||||
-rw-r--r-- | src/cursor/cur_stat.c | 4 | ||||
-rw-r--r-- | src/cursor/cur_std.c | 14 | ||||
-rw-r--r-- | src/cursor/cur_table.c | 5 | ||||
-rw-r--r-- | src/include/cursor.h | 6 | ||||
-rw-r--r-- | src/include/extern.h | 33 | ||||
-rw-r--r-- | src/include/wt_internal.in | 2 | ||||
-rw-r--r-- | src/session/session_root.c | 18 | ||||
-rw-r--r-- | src/support/hex.c | 74 | ||||
-rw-r--r-- | src/support/scratch.c | 14 |
13 files changed, 232 insertions, 135 deletions
diff --git a/src/cursor/cur_config.c b/src/cursor/cur_config.c index e89376adcb3..1563af56417 100644 --- a/src/cursor/cur_config.c +++ b/src/cursor/cur_config.c @@ -67,8 +67,7 @@ __wt_curconfig_open(WT_SESSION_IMPL *session, cursor->key_format = cursor->value_format = "S"; STATIC_ASSERT(offsetof(WT_CURSOR_CONFIG, iface) == 0); - WT_ERR(__wt_cursor_init(cursor, uri, 0, cfg)); - *cursorp = cursor; + WT_ERR(__wt_cursor_init(cursor, uri, 0, cfg, cursorp)); if (0) { err: __wt_free(session, cconfig); diff --git a/src/cursor/cur_dump.c b/src/cursor/cur_dump.c index 79bbbd10d63..d84a4fdf0b9 100644 --- a/src/cursor/cur_dump.c +++ b/src/cursor/cur_dump.c @@ -9,63 +9,36 @@ /* * __raw_to_dump -- - * We have a buffer where the data item contains a raw value, convert it - * to a printable string. + * We have a buffer where the data item contains a raw value, + * convert it to a printable string. */ static int __raw_to_dump( WT_SESSION_IMPL *session, WT_ITEM *from, WT_ITEM *to, int hexonly) { - WT_ITEM *tmp; - uint32_t size; - - /* - * In the worst case, every character takes up 3 spaces, plus a - * trailing nul byte. - */ - WT_RET(__wt_scr_alloc(session, from->size * 3 + 10, &tmp)); - size = from->size; if (hexonly) - __wt_raw_to_hex(from->data, tmp->mem, &size); + WT_RET(__wt_raw_to_hex(session, from->data, from->size, to)); else - __wt_raw_to_esc_hex(from->data, tmp->mem, &size); - tmp->size = size; - - __wt_buf_swap(to, tmp); - __wt_scr_free(&tmp); + WT_RET( + __wt_raw_to_esc_hex(session, from->data, from->size, to)); return (0); } /* * __dump_to_raw -- - * We have a scratch buffer where the data item contains a dump string, + * We have a buffer containing a dump string, * convert it to a raw value. */ static int __dump_to_raw( WT_SESSION_IMPL *session, const char *src_arg, WT_ITEM *item, int hexonly) { - uint32_t size; - - /* - * XXX - * Overwrite the string in place: the underlying cursor set_key and - * set_value functions are going to use the cursor's key and value - * buffers, which means we can't. This should probably be fixed by - * layering the dump cursor on top of other cursors and then we can - * use the dump cursor's key/value buffers. - */ if (hexonly) - WT_RET(__wt_hex_to_raw( - session, (void *)src_arg, (void *)src_arg, &size)); + WT_RET(__wt_hex_to_raw(session, src_arg, item)); else - WT_RET(__wt_esc_hex_to_raw( - session, (void *)src_arg, (void *)src_arg, &size)); + WT_RET(__wt_esc_hex_to_raw(session, src_arg, item)); - memset(item, 0, sizeof(WT_ITEM)); - item->data = src_arg; - item->size = size; return (0); } @@ -76,20 +49,24 @@ __dump_to_raw( static int __curdump_get_key(WT_CURSOR *cursor, ...) { + WT_CURSOR *child; + WT_CURSOR_DUMP *cdump; WT_ITEM item, *itemp; WT_SESSION_IMPL *session; int ret; uint64_t recno; va_list ap; + cdump = (WT_CURSOR_DUMP *)cursor; + child = cdump->child; CURSOR_API_CALL(cursor, session, get_key, NULL); if (WT_CURSOR_RECNO(cursor) && !F_ISSET(cursor, WT_CURSTD_RAW)) { - WT_ERR(cursor->get_key(cursor, &recno)); + WT_ERR(child->get_key(child, &recno)); WT_ERR(__wt_buf_fmt(session, &cursor->key, "%" PRIu64, recno)); } else { - WT_ERR(cursor->get_key(cursor, &item)); + WT_ERR(child->get_key(child, &item)); WT_ERR(__raw_to_dump(session, &item, &cursor->key, F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0)); @@ -144,13 +121,16 @@ format: WT_RET_MSG(session, EINVAL, "%s: invalid record number", p); static void __curdump_set_key(WT_CURSOR *cursor, ...) { - WT_ITEM item; + WT_CURSOR_DUMP *cdump; + WT_CURSOR *child; WT_SESSION_IMPL *session; uint64_t recno; va_list ap; const char *p; int ret; + cdump = (WT_CURSOR_DUMP *)cursor; + child = cdump->child; CURSOR_API_CALL(cursor, session, set_key, NULL); va_start(ap, cursor); @@ -163,12 +143,12 @@ __curdump_set_key(WT_CURSOR *cursor, ...) if (WT_CURSOR_RECNO(cursor) && !F_ISSET(cursor, WT_CURSTD_RAW)) { WT_ERR(str2recno(session, p, &recno)); - cursor->set_key(cursor, recno); + child->set_key(child, recno); } else { - WT_ERR(__dump_to_raw(session, - p, &item, F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0)); + WT_ERR(__dump_to_raw(session, p, &cursor->key, + F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0)); - cursor->set_key(cursor, &item); + child->set_key(child, &cursor->key); } if (0) { @@ -186,14 +166,18 @@ err: cursor->saved_err = ret; static int __curdump_get_value(WT_CURSOR *cursor, ...) { + WT_CURSOR_DUMP *cdump; + WT_CURSOR *child; WT_ITEM item, *itemp; WT_SESSION_IMPL *session; va_list ap; int ret; + cdump = (WT_CURSOR_DUMP *)cursor; + child = cdump->child; CURSOR_API_CALL(cursor, session, get_value, NULL); - WT_ERR(cursor->get_value(cursor, &item)); + WT_ERR(child->get_value(child, &item)); WT_ERR(__raw_to_dump(session, &item, &cursor->value, F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0)); @@ -218,12 +202,15 @@ err: API_END(session); static void __curdump_set_value(WT_CURSOR *cursor, ...) { - WT_ITEM item; + WT_CURSOR_DUMP *cdump; + WT_CURSOR *child; WT_SESSION_IMPL *session; va_list ap; int ret; const char *p; + cdump = (WT_CURSOR_DUMP *)cursor; + child = cdump->child; CURSOR_API_CALL(cursor, session, set_value, NULL); va_start(ap, cursor); @@ -234,9 +221,9 @@ __curdump_set_value(WT_CURSOR *cursor, ...) va_end(ap); WT_ERR(__dump_to_raw(session, - p, &item, F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0)); + p, &cursor->value, F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0)); - cursor->set_value(cursor, &item); + child->set_value(child, &cursor->value); if (0) { err: cursor->saved_err = ret; @@ -246,15 +233,111 @@ err: cursor->saved_err = ret; API_END(session); } +/* Pass through a call to the underlying cursor. */ +#define CURDUMP_PASS(op) \ +static int \ +__curdump_##op(WT_CURSOR *cursor) \ +{ \ + WT_CURSOR_DUMP *cdump; \ + \ + cdump = (WT_CURSOR_DUMP *)cursor; \ + return (cdump->child->op(cdump->child)); \ +} + +CURDUMP_PASS(next) +CURDUMP_PASS(prev) +CURDUMP_PASS(reset) +CURDUMP_PASS(search) + +static int +__curdump_search_near(WT_CURSOR *cursor, int *exact) +{ + WT_CURSOR_DUMP *cdump; + + cdump = (WT_CURSOR_DUMP *)cursor; + return (cdump->child->search_near(cdump->child, exact)); +} + +CURDUMP_PASS(insert) +CURDUMP_PASS(update) +CURDUMP_PASS(remove) + +static int +__curdump_close(WT_CURSOR *cursor) +{ + WT_CURSOR_DUMP *cdump; + WT_CURSOR *child; + WT_SESSION_IMPL *session; + int ret; + + cdump = (WT_CURSOR_DUMP *)cursor; + child = cdump->child; + ret = 0; + + CURSOR_API_CALL(cursor, session, get_key, NULL); + if (child != NULL) + WT_TRET(child->close(child)); + /* We shared the child's URI. */ + cursor->uri = NULL; + WT_TRET(__wt_cursor_close(cursor)); + API_END(session); + + return (ret); +} + /* * __wt_curdump_init -- * initialize a dump cursor. */ -void -__wt_curdump_init(WT_CURSOR *cursor) +int +__wt_curdump_create(WT_CURSOR *child, WT_CURSOR *owner, WT_CURSOR **cursorp) { - cursor->get_key = __curdump_get_key; - cursor->get_value = __curdump_get_value; - cursor->set_key = __curdump_set_key; - cursor->set_value = __curdump_set_value; + static WT_CURSOR iface = { + NULL, + NULL, + NULL, + NULL, + __curdump_get_key, + __curdump_get_value, + __curdump_set_key, + __curdump_set_value, + NULL, + __curdump_next, + __curdump_prev, + __curdump_reset, + __curdump_search, + __curdump_search_near, + __curdump_insert, + __curdump_update, + __curdump_remove, + __curdump_close, + { NULL, NULL }, /* TAILQ_ENTRY q */ + 0, /* recno key */ + { 0 }, /* recno raw buffer */ + { NULL, 0, 0, NULL, 0 },/* WT_ITEM key */ + { NULL, 0, 0, NULL, 0 },/* WT_ITEM value */ + 0, /* int saved_err */ + 0 /* uint32_t flags */ + }; + WT_CURSOR *cursor; + WT_CURSOR_DUMP *cdump; + WT_SESSION_IMPL *session; + const char *cfg[] = API_CONF_DEFAULTS(session, open_cursor, NULL); + + session = (WT_SESSION_IMPL *)child->session; + WT_RET(__wt_calloc_def(session, 1, &cdump)); + cursor = &cdump->iface; + *cursor = iface; + cursor->session = child->session; + cursor->uri = child->uri; + cursor->key_format = child->key_format; + cursor->value_format = child->value_format; + cdump->child = child; + + /* Copy the dump flags from the child cursor. */ + F_SET(cursor, + F_ISSET(child, WT_CURSTD_DUMP_PRINT | WT_CURSTD_DUMP_HEX)); + + WT_RET(__wt_cursor_init(cursor, NULL, owner, cfg, cursorp)); + return (0); } diff --git a/src/cursor/cur_file.c b/src/cursor/cur_file.c index 0be9eec283c..f9e9b35096f 100644 --- a/src/cursor/cur_file.c +++ b/src/cursor/cur_file.c @@ -261,8 +261,7 @@ __wt_curfile_create(WT_SESSION_IMPL *session, WT_ERR(__wt_curbulk_init((WT_CURSOR_BULK *)cbt)); STATIC_ASSERT(offsetof(WT_CURSOR_BTREE, iface) == 0); - WT_ERR(__wt_cursor_init(cursor, cursor->uri, owner, cfg)); - *cursorp = cursor; + WT_ERR(__wt_cursor_init(cursor, cursor->uri, owner, cfg, cursorp)); if (0) { err: __wt_free(session, cbt); diff --git a/src/cursor/cur_index.c b/src/cursor/cur_index.c index 1000953fe7d..efaa8ac48b4 100644 --- a/src/cursor/cur_index.c +++ b/src/cursor/cur_index.c @@ -426,9 +426,7 @@ __wt_curindex_open(WT_SESSION_IMPL *session, /* Open the column groups needed for this index cursor. */ WT_ERR(__curindex_open_colgroups(session, cindex, cfg)); - - WT_ERR(__wt_cursor_init(cursor, cursor->uri, 0, cfg)); - *cursorp = cursor; + WT_ERR(__wt_cursor_init(cursor, cursor->uri, 0, cfg, cursorp)); if (0) { err: (void)__curindex_close(cursor); diff --git a/src/cursor/cur_stat.c b/src/cursor/cur_stat.c index b38982069e5..dbc9d114265 100644 --- a/src/cursor/cur_stat.c +++ b/src/cursor/cur_stat.c @@ -386,9 +386,7 @@ __wt_curstat_open(WT_SESSION_IMPL *session, cst->clear_func = clear_func; STATIC_ASSERT(offsetof(WT_CURSOR_STAT, iface) == 0); - WT_ERR(__wt_cursor_init(cursor, uri, NULL, cfg)); - - *cursorp = cursor; + WT_ERR(__wt_cursor_init(cursor, uri, NULL, cfg, cursorp)); if (0) { err: __wt_free(session, cst); diff --git a/src/cursor/cur_std.c b/src/cursor/cur_std.c index 562c8362419..27659070d15 100644 --- a/src/cursor/cur_std.c +++ b/src/cursor/cur_std.c @@ -371,12 +371,12 @@ err: if (cursor != NULL) */ int __wt_cursor_init(WT_CURSOR *cursor, - const char *uri, WT_CURSOR *owner, const char *cfg[]) + const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) { + WT_CURSOR *cdump; WT_CONFIG_ITEM cval; WT_SESSION_IMPL *session; - WT_UNUSED(cfg); session = (WT_SESSION_IMPL *)cursor->session; if (cursor->get_key == NULL) @@ -407,11 +407,12 @@ __wt_cursor_init(WT_CURSOR *cursor, WT_RET(__wt_config_gets(session, cfg, "dump", &cval)); if (cval.len != 0) { - __wt_curdump_init(cursor); - F_SET(cursor, - strncmp(cval.str, "print", cval.len) == 0 ? + F_SET(cursor, (strncmp(cval.str, "print", cval.len) == 0) ? WT_CURSTD_DUMP_PRINT : WT_CURSTD_DUMP_HEX); - } + WT_RET(__wt_curdump_create(cursor, owner, &cdump)); + owner = cdump; + } else + cdump = NULL; WT_RET(__wt_config_gets(session, cfg, "raw", &cval)); if (cval.val != 0) @@ -434,6 +435,7 @@ __wt_cursor_init(WT_CURSOR *cursor, F_SET(cursor, WT_CURSTD_OPEN); + *cursorp = (cdump != NULL) ? cdump : cursor; return (0); } diff --git a/src/cursor/cur_table.c b/src/cursor/cur_table.c index b2d35d1faf9..f87edd92f34 100644 --- a/src/cursor/cur_table.c +++ b/src/cursor/cur_table.c @@ -598,7 +598,7 @@ __wt_curtable_open(WT_SESSION_IMPL *session, } STATIC_ASSERT(offsetof(WT_CURSOR_TABLE, iface) == 0); - WT_ERR(__wt_cursor_init(cursor, cursor->uri, NULL, cfg)); + WT_ERR(__wt_cursor_init(cursor, cursor->uri, NULL, cfg, cursorp)); /* * Open the colgroup cursors immediately: we're going to need them for @@ -610,10 +610,9 @@ __wt_curtable_open(WT_SESSION_IMPL *session, */ WT_ERR(__curtable_open_colgroups(ctable, cfg)); - *cursorp = cursor; - if (0) { err: (void)__curtable_close(cursor); + *cursorp = NULL; } return (ret); diff --git a/src/include/cursor.h b/src/include/cursor.h index d858505a99e..6dc01a44437 100644 --- a/src/include/cursor.h +++ b/src/include/cursor.h @@ -120,6 +120,12 @@ struct __wt_cursor_config { WT_CURSOR iface; }; +struct __wt_cursor_dump { + WT_CURSOR iface; + + WT_CURSOR *child; +}; + struct __wt_cursor_index { WT_CURSOR_BTREE cbt; diff --git a/src/include/extern.h b/src/include/extern.h index 1b9f45a7ce9..7f9e633a702 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -455,7 +455,9 @@ extern int __wt_curconfig_open(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR **cursorp); -extern void __wt_curdump_init(WT_CURSOR *cursor); +extern int __wt_curdump_create(WT_CURSOR *child, + WT_CURSOR *owner, + WT_CURSOR **cursorp); extern int __wt_curfile_create(WT_SESSION_IMPL *session, WT_CURSOR *owner, const char *cfg[], @@ -487,7 +489,8 @@ extern int __wt_cursor_dup(WT_SESSION_IMPL *session, extern int __wt_cursor_init(WT_CURSOR *cursor, const char *uri, WT_CURSOR *owner, - const char *cfg[]); + const char *cfg[], + WT_CURSOR **cursorp); extern int __wt_cursor_kv_not_set(WT_CURSOR *cursor, int key); extern int __wt_curtable_get_key(WT_CURSOR *cursor, ...); extern int __wt_curtable_get_value(WT_CURSOR *cursor, ...); @@ -771,7 +774,7 @@ extern int __wt_btree_get_root(WT_SESSION_IMPL *session, WT_ITEM *addr); extern int __wt_btree_free_root(WT_SESSION_IMPL *session); extern int __wt_btree_set_root(WT_SESSION_IMPL *session, const char *filename, - uint8_t *addr, + const uint8_t *addr, uint32_t size); extern void __wt_eventv(WT_SESSION_IMPL *session, int msg_event, @@ -827,16 +830,20 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref extern void __wt_hazard_clear(WT_SESSION_IMPL *session, WT_PAGE *page); extern void __wt_hazard_empty(WT_SESSION_IMPL *session); extern void __wt_hazard_validate(WT_SESSION_IMPL *session, WT_PAGE *page); -extern void __wt_raw_to_hex(const void *from, void *to, uint32_t *sizep); -extern void __wt_raw_to_esc_hex(const void *from, void *to, uint32_t *sizep); -extern int __wt_hex_to_raw( WT_SESSION_IMPL *session, - void *from, - void *to, - uint32_t *sizep); -extern int __wt_esc_hex_to_raw( WT_SESSION_IMPL *session, - void *from, - void *to, - uint32_t *sizep); +extern int __wt_raw_to_hex(WT_SESSION_IMPL *session, + const uint8_t *from, + uint32_t size, + WT_ITEM *to); +extern int __wt_raw_to_esc_hex(WT_SESSION_IMPL *session, + const uint8_t *from, + size_t size, + WT_ITEM *to); +extern int __wt_hex_to_raw(WT_SESSION_IMPL *session, + const char *from, + WT_ITEM *to); +extern int __wt_esc_hex_to_raw(WT_SESSION_IMPL *session, + const char *from, + WT_ITEM *to); extern int __wt_huffman_open(WT_SESSION_IMPL *session, void *symbol_frequency_array, u_int symcnt, diff --git a/src/include/wt_internal.in b/src/include/wt_internal.in index 638bf79373d..803f9cf704b 100644 --- a/src/include/wt_internal.in +++ b/src/include/wt_internal.in @@ -86,6 +86,8 @@ struct __wt_cursor_bulk; typedef struct __wt_cursor_bulk WT_CURSOR_BULK; struct __wt_cursor_config; typedef struct __wt_cursor_config WT_CURSOR_CONFIG; +struct __wt_cursor_dump; + typedef struct __wt_cursor_dump WT_CURSOR_DUMP; struct __wt_cursor_index; typedef struct __wt_cursor_index WT_CURSOR_INDEX; struct __wt_cursor_stat; diff --git a/src/session/session_root.c b/src/session/session_root.c index 4a8ec127ddf..5d7d8b76540 100644 --- a/src/session/session_root.c +++ b/src/session/session_root.c @@ -28,7 +28,6 @@ int __wt_btree_get_root(WT_SESSION_IMPL *session, WT_ITEM *addr) { WT_BTREE *btree; - uint32_t size; int majorv, minorv, ret; const char *v; @@ -59,10 +58,8 @@ __wt_btree_get_root(WT_SESSION_IMPL *session, WT_ITEM *addr) "%s is an unsupported version of a WiredTiger file", btree->filename); - if (v != NULL && strlen(v) != 0 && strcmp(v, WT_NOADDR) != 0) { - WT_ERR(__wt_hex_to_raw(session, (void *)v, (void *)v, &size)); - WT_ERR(__wt_buf_set(session, addr, v, size)); - } + if (v != NULL && strlen(v) != 0 && strcmp(v, WT_NOADDR) != 0) + WT_ERR(__wt_hex_to_raw(session, v, addr)); err: if (ret != 0) __wt_errx(session, @@ -108,7 +105,7 @@ err: __wt_scr_free(&addr); */ int __wt_btree_set_root(WT_SESSION_IMPL *session, - const char *filename, uint8_t *addr, uint32_t size) + const char *filename, const uint8_t *addr, uint32_t size) { WT_ITEM *v; int ret; @@ -118,7 +115,7 @@ __wt_btree_set_root(WT_SESSION_IMPL *session, /* * Every bytes is encoded as 2 bytes, plus a trailing nul byte, - * and it needs to hold the [NoAddr] string. + * and it needs to hold the "no address" string. */ WT_RET(__wt_scr_alloc( session, size * 2 + 1 + WT_STORE_SIZE(strlen(WT_NOADDR)), &v)); @@ -133,11 +130,8 @@ __wt_btree_set_root(WT_SESSION_IMPL *session, if (addr == NULL) { v->data = WT_NOADDR; v->size = WT_STORE_SIZE(strlen(WT_NOADDR)) + 1; - } else { - __wt_raw_to_hex(addr, v->mem, &size); - v->data = v->mem; - v->size = size; - } + } else + WT_ERR(__wt_raw_to_hex(session, addr, size, v)); WT_ERR(strcmp(filename, WT_SCHEMA_FILENAME) == 0 ? __btree_set_turtle(session, v) : diff --git a/src/support/hex.c b/src/support/hex.c index e23118d2a22..e582e9576ef 100644 --- a/src/support/hex.c +++ b/src/support/hex.c @@ -7,44 +7,59 @@ #include "wt_internal.h" -static const u_char hex[] = "0123456789abcdef"; +static const char hex[] = "0123456789abcdef"; /* * __wt_raw_to_hex -- * Convert a chunk of data to a printable hex string. */ -void -__wt_raw_to_hex(const void *from, void *to, uint32_t *sizep) +int +__wt_raw_to_hex(WT_SESSION_IMPL *session, + const uint8_t *from, uint32_t size, WT_ITEM *to) { uint32_t i; const uint8_t *p; - uint8_t *t, *t_start; + char *t; + + /* + * In the worst case, every character takes up 2 spaces, plus a + * trailing nul byte. + */ + WT_RET(__wt_buf_init(session, to, size * 2 + 1)); - for (p = from, t = t_start = to, i = *sizep; i > 0; --i, ++p) { + for (p = from, t = to->mem, i = size; i > 0; --i, ++p) { *t++ = hex[(*p & 0xf0) >> 4]; *t++ = hex[*p & 0x0f]; } *t++ = '\0'; - *sizep = WT_PTRDIFF32(t, t_start); + to->size = WT_PTRDIFF32(t, to->mem); + return (0); } /* * __wt_raw_to_esc_hex -- * Convert a chunk of data to an printable string using escaped hex as - * necessary. + * necessary. */ -void -__wt_raw_to_esc_hex(const void *from, void *to, uint32_t *sizep) +int +__wt_raw_to_esc_hex(WT_SESSION_IMPL *session, + const uint8_t *from, size_t size, WT_ITEM *to) { - uint32_t i; + size_t i; const uint8_t *p; - uint8_t *t, *t_start; + uint8_t *t; /* * In the worst case, every character takes up 3 spaces, plus a * trailing nul byte. */ - for (p = from, t = t_start = to, i = *sizep; i > 0; --i, ++p) + WT_RET(__wt_buf_init(session, to, size * 3 + 1)); + + /* + * In the worst case, every character takes up 3 spaces, plus a + * trailing nul byte. + */ + for (p = from, t = to->mem, i = size; i > 0; --i, ++p) if (isprint((int)*p)) { if (*p == '\\') *t++ = '\\'; @@ -55,7 +70,8 @@ __wt_raw_to_esc_hex(const void *from, void *to, uint32_t *sizep) *t++ = hex[*p & 0x0f]; } *t++ = '\0'; - *sizep = WT_PTRDIFF32(t, t_start); + to->size = WT_PTRDIFF32(t, to->mem); + return (0); } /* @@ -63,7 +79,7 @@ __wt_raw_to_esc_hex(const void *from, void *to, uint32_t *sizep) * Convert a pair of hex characters into a byte. */ static inline int -hex2byte(uint8_t *from, uint8_t *to) +hex2byte(const char *from, uint8_t *to) { uint8_t byte; @@ -123,34 +139,40 @@ __hex_fmterr(WT_SESSION_IMPL *session) * Convert a printable hex string to a chunk of data. */ int -__wt_hex_to_raw( - WT_SESSION_IMPL *session, void *from, void *to, uint32_t *sizep) +__wt_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to) { - uint8_t *p, *t, *t_start; + const char *p; + uint8_t *t; + size_t size; - if (strlen(from) % 2 != 0) + size = strlen(from); + if (size % 2 != 0) return (__hex_fmterr(session)); - for (p = from, t = t_start = to; *p != '\0'; p += 2, ++t) + WT_RET(__wt_buf_init(session, to, size / 2)); + + for (p = from, t = to->mem; *p != '\0'; p += 2, ++t) if (hex2byte(p, t)) return (__hex_fmterr(session)); - *sizep = WT_PTRDIFF32(t, t_start); + to->size = WT_PTRDIFF32(t, to->mem); return (0); } /* * __wt_esc_hex_to_raw -- * Convert a printable string using escaped hex as necessary to a chunk - * of data. + * of data. */ int -__wt_esc_hex_to_raw( - WT_SESSION_IMPL *session, void *from, void *to, uint32_t *sizep) +__wt_esc_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to) { - uint8_t *p, *t, *t_start; + const char *p; + uint8_t *t; + + WT_RET(__wt_buf_init(session, to, strlen(from))); - for (p = from, t = t_start = to; *p != '\0'; ++p, ++t) { + for (p = from, t = to->mem; *p != '\0'; ++p, ++t) { if ((*t = *p) != '\\') continue; ++p; @@ -160,6 +182,6 @@ __wt_esc_hex_to_raw( ++p; } } - *sizep = WT_PTRDIFF32(t, t_start); + to->size = WT_PTRDIFF32(t, to->mem); return (0); } diff --git a/src/support/scratch.c b/src/support/scratch.c index e14b4ec2240..cd4cbb0cca6 100644 --- a/src/support/scratch.c +++ b/src/support/scratch.c @@ -120,19 +120,7 @@ int __wt_buf_set_printable( WT_SESSION_IMPL *session, WT_ITEM *buf, const void *from_arg, size_t size) { - uint32_t u32size; - - /* - * In the worst case, every character takes up 3 spaces, plus a - * trailing nul byte. - */ - WT_RET(__wt_buf_init(session, buf, size * 3 + 10)); - - u32size = (uint32_t)size; - __wt_raw_to_esc_hex(from_arg, buf->mem, &u32size); - buf->size = u32size; - - return (0); + return (__wt_raw_to_esc_hex(session, from_arg, size, buf)); } /* |