summaryrefslogtreecommitdiff
path: root/src/packing/pack_impl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/packing/pack_impl.c')
-rw-r--r--src/packing/pack_impl.c87
1 files changed, 15 insertions, 72 deletions
diff --git a/src/packing/pack_impl.c b/src/packing/pack_impl.c
index 0e3ed44ba6a..5dbb0f33842 100644
--- a/src/packing/pack_impl.c
+++ b/src/packing/pack_impl.c
@@ -107,36 +107,6 @@ __wt_struct_unpack(WT_SESSION_IMPL *session,
}
/*
- * __wt_struct_unpack_size --
- * Determine the packed size of a buffer matching the format.
- */
-int
-__wt_struct_unpack_size(WT_SESSION_IMPL *session,
- const void *buffer, size_t size, const char *fmt, size_t *resultp)
-{
- WT_DECL_PACK_VALUE(pv);
- WT_DECL_RET;
- WT_PACK pack;
- const uint8_t *p, *end;
-
- p = buffer;
- end = p + size;
-
- WT_RET(__pack_init(session, &pack, fmt));
- while ((ret = __pack_next(&pack, &pv)) == 0)
- WT_RET(__unpack_read(session, &pv, &p, (size_t)(end - p)));
-
- /* Be paranoid - __pack_write should never overflow. */
- WT_ASSERT(session, p <= end);
-
- if (ret != WT_NOTFOUND)
- return (ret);
-
- *resultp = WT_PTRDIFF(p, buffer);
- return (0);
-}
-
-/*
* __wt_struct_repack --
* Return the subset of the packed buffer that represents part of
* the format. If the result is not contiguous in the existing
@@ -144,70 +114,43 @@ __wt_struct_unpack_size(WT_SESSION_IMPL *session,
*/
int
__wt_struct_repack(WT_SESSION_IMPL *session, const char *infmt,
- const char *outfmt, const WT_ITEM *inbuf, WT_ITEM *outbuf, void **reallocp)
+ const char *outfmt, const WT_ITEM *inbuf, WT_ITEM *outbuf)
{
WT_DECL_PACK_VALUE(pvin);
WT_DECL_PACK_VALUE(pvout);
WT_DECL_RET;
WT_PACK packin, packout;
const uint8_t *before, *end, *p;
- uint8_t *pout;
- size_t len;
const void *start;
start = NULL;
p = inbuf->data;
end = p + inbuf->size;
- /*
- * Handle this non-contiguous case: 'U' -> 'u' at the end of the buf.
- * The former case has the size embedded before the item, the latter
- * does not.
- */
- if ((len = strlen(outfmt)) > 1 && outfmt[len - 1] == 'u' &&
- strlen(infmt) > len && infmt[len - 1] == 'U') {
- WT_ERR(__wt_realloc(session, NULL, inbuf->size, reallocp));
- pout = *reallocp;
- } else
- pout = NULL;
-
- WT_ERR(__pack_init(session, &packout, outfmt));
- WT_ERR(__pack_init(session, &packin, infmt));
+ WT_RET(__pack_init(session, &packout, outfmt));
+ WT_RET(__pack_init(session, &packin, infmt));
/* Outfmt should complete before infmt */
while ((ret = __pack_next(&packout, &pvout)) == 0) {
if (p >= end)
- WT_ERR(EINVAL);
- WT_ERR(__pack_next(&packin, &pvin));
+ WT_RET(EINVAL);
+ if (pvout.type == 'x' && pvout.size == 0 && pvout.havesize)
+ continue;
+ WT_RET(__pack_next(&packin, &pvin));
before = p;
- WT_ERR(__unpack_read(session, &pvin, &p, (size_t)(end - p)));
- if (pvout.type != pvin.type) {
- if (pvout.type == 'u' && pvin.type == 'U') {
- /* Skip the prefixed size, we don't need it */
- WT_ERR(__wt_struct_unpack_size(session, before,
- (size_t)(end - before), "I", &len));
- before += len;
- } else
- WT_ERR(ENOTSUP);
- }
- if (pout != NULL) {
- memcpy(pout, before, WT_PTRDIFF(p, before));
- pout += p - before;
- } else if (start == NULL)
+ WT_RET(__unpack_read(session, &pvin, &p, (size_t)(end - p)));
+ if (pvout.type != pvin.type)
+ WT_RET(ENOTSUP);
+ if (start == NULL)
start = before;
}
- WT_ERR_NOTFOUND_OK(ret);
+ WT_RET_NOTFOUND_OK(ret);
/* Be paranoid - __pack_write should never overflow. */
WT_ASSERT(session, p <= end);
- if (pout != NULL) {
- outbuf->data = *reallocp;
- outbuf->size = WT_PTRDIFF(pout, *reallocp);
- } else {
- outbuf->data = start;
- outbuf->size = WT_PTRDIFF(p, start);
- }
+ outbuf->data = start;
+ outbuf->size = WT_PTRDIFF(p, start);
-err: return (ret);
+ return (0);
}