diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2013-02-22 12:19:02 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2013-02-22 12:19:02 +1100 |
commit | 7afc6b1e88b548a174b06acbbad5c0977304b5ad (patch) | |
tree | c344d0ad43e5a716f6a5351dc92279ab1188caac | |
parent | 77f22f56608b6bc5886584866434460421a95cf5 (diff) | |
download | mongo-7afc6b1e88b548a174b06acbbad5c0977304b5ad.tar.gz |
Add documentation and checking to pack streams, return the number of bytes (un)packed.
-rw-r--r-- | src/include/wiredtiger.in | 115 | ||||
-rw-r--r-- | src/packing/pack_stream.c | 166 |
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); } |