summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2013-02-22 12:19:02 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2013-02-22 12:19:02 +1100
commit7afc6b1e88b548a174b06acbbad5c0977304b5ad (patch)
treec344d0ad43e5a716f6a5351dc92279ab1188caac
parent77f22f56608b6bc5886584866434460421a95cf5 (diff)
downloadmongo-7afc6b1e88b548a174b06acbbad5c0977304b5ad.tar.gz
Add documentation and checking to pack streams, return the number of bytes (un)packed.
-rw-r--r--src/include/wiredtiger.in115
-rw-r--r--src/packing/pack_stream.c166
2 files changed, 250 insertions, 31 deletions
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index b70fb10b654..5fab5bc1a18 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -581,7 +581,7 @@ struct __wt_session {
* @config{target, if non-empty\, backup the list of objects; valid only
* for a backup data source.,a list of strings; default empty.}
* @configend
- * @param cursorp a pointer to the newly opened cursor
+ * @param[out] cursorp a pointer to the newly opened cursor
* @errors
*/
int __F(open_cursor)(WT_SESSION *session,
@@ -1109,7 +1109,7 @@ struct __wt_connection {
* "read-uncommitted"\, \c "read-committed"\, \c "snapshot"; default \c
* read-committed.}
* @configend
- * @param sessionp the new session handle
+ * @param[out] sessionp the new session handle
* @errors
*/
int __F(open_session)(WT_CONNECTION *connection,
@@ -1292,7 +1292,7 @@ struct __wt_connection {
* for details). Configuration values specified in the \c config argument to
* the ::wiredtiger_open function override configuration values specified in
* the \c WiredTiger.config file.
- * @param connectionp A pointer to the newly opened connection handle
+ * @param[out] connectionp A pointer to the newly opened connection handle
* @errors
*/
int wiredtiger_open(const char *home,
@@ -1357,6 +1357,9 @@ struct __wt_event_handler {
const char *operation, uint64_t progress);
};
+/*! @name Data packing and unpacking
+ * @{
+ */
/*! Pack a structure into a buffer.
*
* See @ref packing for a description of the permitted format strings.
@@ -1415,27 +1418,129 @@ int wiredtiger_struct_size(
int wiredtiger_struct_unpack(WT_SESSION *session,
const void *buffer, size_t size, const char *format, ...);
-/*
+/*!
* Streaming interface to packing.
*
* This allows applications to pack or unpack records one field at a time.
+ * This is an opaque handle returned by ::wiredtiger_pack_start or
+ * ::wiredtiger_unpack_start. It must be closed with ::wiredtiger_pack_close.
*/
typedef struct __wt_pack_stream WT_PACK_STREAM;
+/*!
+ * Start a packing operation into a buffer with the given format string. This
+ * should be followed by a series of calls to ::wiredtiger_pack_item,
+ * ::wiredtiger_pack_int, ::wiredtiger_pack_str or ::wiredtiger_pack_uint
+ * to fill in the values.
+ *
+ * @param session the session handle
+ * @param format the data format, see @ref packing
+ * @param buffer a pointer to memory to hold the packed data
+ * @param size the size of the buffer
+ * @param[out] psp the new packing stream handle
+ * @errors
+ */
int wiredtiger_pack_start(WT_SESSION *session, const char *format, void *buffer, size_t size, WT_PACK_STREAM **psp);
+
+/*!
+ * Start an unpacking operation from a buffer with the given format string. This
+ * should be followed by a series of calls to ::wiredtiger_unpack_item,
+ * ::wiredtiger_unpack_int, ::wiredtiger_unpack_str or ::wiredtiger_unpack_uint
+ * to retrieve the packed values.
+ *
+ * @param session the session handle
+ * @param format the data format, see @ref packing
+ * @param buffer a pointer to memory holding the packed data
+ * @param size the size of the buffer
+ * @param[out] psp the new packing stream handle
+ * @errors
+ */
int wiredtiger_unpack_start(WT_SESSION *session, const char *format, const void *buffer, size_t size, WT_PACK_STREAM **psp);
+/*!
+ * Close a packing stream.
+ *
+ * @param ps the packing stream handle
+ * @param[out] usedp the number of bytes in the buffer used by the stream
+ * @errors
+ */
+int wiredtiger_pack_close(WT_PACK_STREAM *ps, size_t *usedp);
+
+/*!
+ * Pack an item into a packing stream.
+ *
+ * @param ps the packing stream handle
+ * @param item an item to pack
+ * @errors
+ */
int wiredtiger_pack_item(WT_PACK_STREAM *ps, WT_ITEM *item);
+
+/*!
+ * Pack a signed integer into a packing stream.
+ *
+ * @param ps the packing stream handle
+ * @param i a signed integer to pack
+ * @errors
+ */
int wiredtiger_pack_int(WT_PACK_STREAM *ps, int64_t i);
+
+/*!
+ * Pack a string into a packing stream.
+ *
+ * @param ps the packing stream handle
+ * @param s a string to pack
+ * @errors
+ */
int wiredtiger_pack_str(WT_PACK_STREAM *ps, const char *s);
+
+/*!
+ * Pack an unsigned integer into a packing stream.
+ *
+ * @param ps the packing stream handle
+ * @param u an unsigned integer to pack
+ * @errors
+ */
int wiredtiger_pack_uint(WT_PACK_STREAM *ps, uint64_t u);
+/*!
+ * Unpack an item from a packing stream.
+ *
+ * @param ps the packing stream handle
+ * @param item an item to unpack
+ * @errors
+ */
int wiredtiger_unpack_item(WT_PACK_STREAM *ps, WT_ITEM *item);
+
+/*!
+ * Unpack a signed interger from a packing stream.
+ *
+ * @param ps the packing stream handle
+ * @param[out] ip the unpacked signed integer
+ * @errors
+ */
int wiredtiger_unpack_int(WT_PACK_STREAM *ps, int64_t *ip);
+
+/*!
+ * Unpack a string from a packing stream.
+ *
+ * @param ps the packing stream handle
+ * @param[out] sp the unpacked string
+ * @errors
+ */
int wiredtiger_unpack_str(WT_PACK_STREAM *ps, const char **sp);
+
+/*!
+ * Unpack an unsigned interger from a packing stream.
+ *
+ * @param ps the packing stream handle
+ * @param[out] up the unpacked unsigned integer
+ * @errors
+ */
int wiredtiger_unpack_uint(WT_PACK_STREAM *ps, uint64_t *up);
-int wiredtiger_pack_close(WT_PACK_STREAM *ps);
+/*!
+ * @}
+ */
/*! Get version information.
*
diff --git a/src/packing/pack_stream.c b/src/packing/pack_stream.c
index fcb4a10aabc..977f08749bb 100644
--- a/src/packing/pack_stream.c
+++ b/src/packing/pack_stream.c
@@ -14,9 +14,13 @@
*/
struct __wt_pack_stream {
WT_PACK pack;
- uint8_t *end, *p;
+ uint8_t *end, *p, *start;
};
+/*
+ * wiredtiger_pack_start --
+ * Open a stream for packing.
+ */
int
wiredtiger_pack_start(WT_SESSION *wt_session, const char *format, void *buffer, size_t len, WT_PACK_STREAM **psp)
{
@@ -27,31 +31,46 @@ wiredtiger_pack_start(WT_SESSION *wt_session, const char *format, void *buffer,
session = (WT_SESSION_IMPL *)wt_session;
WT_RET(__wt_calloc_def(session, 1, &ps));
WT_ERR(__pack_init(session, &ps->pack, format));
- ps->p = buffer;
+ ps->p = ps->start = buffer;
ps->end = ps->p + len;
*psp = ps;
if (0) {
-err: (void)wiredtiger_pack_close(ps);
+err: (void)wiredtiger_pack_close(ps, NULL);
}
return (ret);
}
+/*
+ * wiredtiger_unpack_start --
+ * Open a stream for unpacking.
+ */
int
wiredtiger_unpack_start(WT_SESSION *wt_session, const char *format, const void *buffer, size_t size, WT_PACK_STREAM **psp)
{
return (wiredtiger_pack_start(wt_session, format, (void *)buffer, size, psp));
}
+/*
+ * wiredtiger_pack_close --
+ * Close a packing stream.
+ */
int
-wiredtiger_pack_close(WT_PACK_STREAM *ps)
+wiredtiger_pack_close(WT_PACK_STREAM *ps, size_t *usedp)
{
if (ps != NULL)
__wt_free(ps->pack.session, ps);
+ if (usedp != NULL)
+ *usedp = WT_PTRDIFF(ps->p, ps->start);
+
return (0);
}
+/*
+ * wiredtiger_pack_item --
+ * Pack an item.
+ */
int
wiredtiger_pack_item(WT_PACK_STREAM *ps, WT_ITEM *item)
{
@@ -60,13 +79,23 @@ wiredtiger_pack_item(WT_PACK_STREAM *ps, WT_ITEM *item)
session = ps->pack.session;
WT_RET(__pack_next(&ps->pack, &pv));
- pv.u.item.data = item->data;
- pv.u.item.size = item->size;
- WT_RET(__pack_write(session, &pv, &ps->p, (size_t)(ps->end - ps->p)));
+ switch (pv.type) {
+ case 'U':
+ case 'u':
+ pv.u.item.data = item->data;
+ pv.u.item.size = item->size;
+ WT_RET(__pack_write(session, &pv, &ps->p, (size_t)(ps->end - ps->p)));
+ break;
+ WT_ILLEGAL_VALUE(session);
+ }
return (0);
}
+/*
+ * wiredtiger_pack_int --
+ * Pack a signed integer.
+ */
int
wiredtiger_pack_int(WT_PACK_STREAM *ps, int64_t i)
{
@@ -75,12 +104,25 @@ wiredtiger_pack_int(WT_PACK_STREAM *ps, int64_t i)
session = ps->pack.session;
WT_RET(__pack_next(&ps->pack, &pv));
- pv.u.i = i;
- WT_RET(__pack_write(session, &pv, &ps->p, (size_t)(ps->end - ps->p)));
+ switch (pv.type) {
+ case 'b':
+ case 'h':
+ case 'i':
+ case 'l':
+ case 'q':
+ pv.u.i = i;
+ WT_RET(__pack_write(session, &pv, &ps->p, (size_t)(ps->end - ps->p)));
+ break;
+ WT_ILLEGAL_VALUE(session);
+ }
return (0);
}
+/*
+ * wiredtiger_pack_str --
+ * Pack a string.
+ */
int
wiredtiger_pack_str(WT_PACK_STREAM *ps, const char *s)
{
@@ -89,12 +131,22 @@ wiredtiger_pack_str(WT_PACK_STREAM *ps, const char *s)
session = ps->pack.session;
WT_RET(__pack_next(&ps->pack, &pv));
- pv.u.s = s;
- WT_RET(__pack_write(session, &pv, &ps->p, (size_t)(ps->end - ps->p)));
+ switch (pv.type) {
+ case 'S':
+ case 's':
+ pv.u.s = s;
+ WT_RET(__pack_write(session, &pv, &ps->p, (size_t)(ps->end - ps->p)));
+ break;
+ WT_ILLEGAL_VALUE(session);
+ }
return (0);
}
+/*
+ * wiredtiger_pack_uint --
+ * Pack an unsigned int.
+ */
int
wiredtiger_pack_uint(WT_PACK_STREAM *ps, uint64_t u)
{
@@ -103,12 +155,28 @@ wiredtiger_pack_uint(WT_PACK_STREAM *ps, uint64_t u)
session = ps->pack.session;
WT_RET(__pack_next(&ps->pack, &pv));
- pv.u.u = u;
- WT_RET(__pack_write(session, &pv, &ps->p, (size_t)(ps->end - ps->p)));
+ switch (pv.type) {
+ case 'B':
+ case 'H':
+ case 'I':
+ case 'L':
+ case 'Q':
+ case 'R':
+ case 'r':
+ case 't':
+ pv.u.u = u;
+ WT_RET(__pack_write(session, &pv, &ps->p, (size_t)(ps->end - ps->p)));
+ break;
+ WT_ILLEGAL_VALUE(session);
+ }
return (0);
}
+/*
+ * wiredtiger_unpack_item --
+ * Unpack an item.
+ */
int
wiredtiger_unpack_item(WT_PACK_STREAM *ps, WT_ITEM *item)
{
@@ -117,13 +185,24 @@ wiredtiger_unpack_item(WT_PACK_STREAM *ps, WT_ITEM *item)
session = ps->pack.session;
WT_RET(__pack_next(&ps->pack, &pv));
- WT_RET(__unpack_read(session,
- &pv, (const uint8_t **)&ps->p, (size_t)(ps->end - ps->p)));
- item->data = pv.u.item.data;
- item->size = pv.u.item.size;
+ switch (pv.type) {
+ case 'U':
+ case 'u':
+ WT_RET(__unpack_read(session,
+ &pv, (const uint8_t **)&ps->p, (size_t)(ps->end - ps->p)));
+ item->data = pv.u.item.data;
+ item->size = pv.u.item.size;
+ break;
+ WT_ILLEGAL_VALUE(session);
+ }
+
return (0);
}
+/*
+ * wiredtiger_unpack_int --
+ * Unpack a signed integer.
+ */
int
wiredtiger_unpack_int(WT_PACK_STREAM *ps, int64_t *ip)
{
@@ -132,12 +211,25 @@ wiredtiger_unpack_int(WT_PACK_STREAM *ps, int64_t *ip)
session = ps->pack.session;
WT_RET(__pack_next(&ps->pack, &pv));
- WT_RET(__unpack_read(session,
- &pv, (const uint8_t **)&ps->p, (size_t)(ps->end - ps->p)));
- *ip = pv.u.i;
+ switch (pv.type) {
+ case 'b':
+ case 'h':
+ case 'i':
+ case 'l':
+ case 'q':
+ WT_RET(__unpack_read(session,
+ &pv, (const uint8_t **)&ps->p, (size_t)(ps->end - ps->p)));
+ *ip = pv.u.i;
+ break;
+ WT_ILLEGAL_VALUE(session);
+ }
return (0);
}
+/*
+ * wiredtiger_unpack_str --
+ * Unpack a string.
+ */
int
wiredtiger_unpack_str(WT_PACK_STREAM *ps, const char **sp)
{
@@ -146,12 +238,22 @@ wiredtiger_unpack_str(WT_PACK_STREAM *ps, const char **sp)
session = ps->pack.session;
WT_RET(__pack_next(&ps->pack, &pv));
- WT_RET(__unpack_read(session,
- &pv, (const uint8_t **)&ps->p, (size_t)(ps->end - ps->p)));
- *sp = pv.u.s;
+ switch (pv.type) {
+ case 'S':
+ case 's':
+ WT_RET(__unpack_read(session,
+ &pv, (const uint8_t **)&ps->p, (size_t)(ps->end - ps->p)));
+ *sp = pv.u.s;
+ break;
+ WT_ILLEGAL_VALUE(session);
+ }
return (0);
}
+/*
+ * wiredtiger_unpack_uint --
+ * Unpack an unsigned integer.
+ */
int
wiredtiger_unpack_uint(WT_PACK_STREAM *ps, uint64_t *up)
{
@@ -160,8 +262,20 @@ wiredtiger_unpack_uint(WT_PACK_STREAM *ps, uint64_t *up)
session = ps->pack.session;
WT_RET(__pack_next(&ps->pack, &pv));
- WT_RET(__unpack_read(session,
- &pv, (const uint8_t **)&ps->p, (size_t)(ps->end - ps->p)));
- *up = pv.u.u;
+ switch (pv.type) {
+ case 'B':
+ case 'H':
+ case 'I':
+ case 'L':
+ case 'Q':
+ case 'R':
+ case 'r':
+ case 't':
+ WT_RET(__unpack_read(session,
+ &pv, (const uint8_t **)&ps->p, (size_t)(ps->end - ps->p)));
+ *up = pv.u.u;
+ break;
+ WT_ILLEGAL_VALUE(session);
+ }
return (0);
}