diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac69a1..446a99b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,48 +1,39 @@ -Unreleased -========== - -MPack develop (tentatively v0.9) --------------------------------------------- +MPack v1.0 +---------- -A number of breaking API changes will be made as we approach a 1.0 release. Please take note of these changes when upgrading. +A number of breaking API changes have been made for the 1.0 release. Please take note of these changes when upgrading. Breaking Changes: - The Node API now separates tree initialization from parsing. After calling one of the `mpack_tree_init()` functions, you must explicitly call `mpack_tree_parse()` before accessing any nodes. -- `mpack_tag_t` is now considered an opaque type (to prevent future breakage when changing its layout.) Compatibility is maintained for this release, but this may change in future releases. - -- The mpack configuration `mpack-config.h` file is now optional, and requires `MPACK_HAS_CONFIG` in order to be included. This means you must define `MPACK_HAS_CONFIG` when upgrading or your config file will be ignored! (It is recommended to delete your config file and use the defaults.) +- The configuration file `mpack-config.h` is now optional, and requires `MPACK_HAS_CONFIG` in order to be included. This means you must define `MPACK_HAS_CONFIG` when upgrading or your config file will be ignored! - Extension types are now disabled by default. You must define `MPACK_EXTENSIONS` to use them. -- Compatibility with the v4 MessagePack spec is now disabled by default. You must define `MPACK_COMPATIBILITY` to use it. +- `mpack_tag_t` is now considered an opaque type to prevent future breakage when changing its layout. Compatibility is maintained for this release, but this may change in future releases. New Features: -- The timestamp type has been implemented. A timestamp is a signed number of nanoseconds since January 1st, 1970 at 12:00 UTC. (This requires `MPACK_EXTENSIONS`.) - - The Node API can now parse multiple messages from a data source. `mpack_tree_parse()` can be called repeatedly to parse each message. - The Node API can now parse messages indefinitely from a continuous stream. A tree can be initialized with `mpack_tree_init_stream()` to receive a callback for more data. -- The Node API can now parse messages incrementally from a non-blocking stream. Call `mpack_tree_try_parse()` to continue parsing. It will return true when a complete message has become available. +- The Node API can now parse messages incrementally from a non-blocking stream. Call `mpack_tree_try_parse()` with a non-blocking read function to start and resume parsing. It will return true when a complete message has become available. -- The writer now supports a v4 compatibility mode. Call `mpack_writer_set_version(writer, mpack_version_v4);` to encode without using the `raw8`, `bin`, `ext` and `timestamp` types. - -- The stdio helpers now allow reading from a `FILE*`. `_init_file()` functions have been renamed to `_init_filename()`. The old names will continue to work for a few more versions. +- The stdio helpers now allow reading from a `FILE*`. `_init_file()` functions have been renamed to `_init_filename()`. (The old names will continue to work for a few more versions.) - The Node API now returns a node of "missing" type instead of "nil" type for optional map lookups. This allows the caller to tell the difference between a key having value nil and a missing key. -Changes: +- The writer now supports a v4 compatibility mode. Call `mpack_writer_set_version(writer, mpack_version_v4);` to encode without using the `raw8`, `bin` and `ext` types. (This requires `MPACK_COMPATIBILITY`.) -- The reader's skip function is no longer ignored under `MPACK_OPTIMIZE_FOR_SIZE`. +- The timestamp type has been implemented. A timestamp is a signed number of nanoseconds since the Unix epoch (1970-01-01T00:00:00Z). (This requires `MPACK_EXTENSIONS`.) -- Fixed an allocation bug when closing a growable writer without having written anything. +Bug Fixes and Other Changes: +- Fixed an allocation bug when closing a growable writer without having written anything (#58). -Release Versions -================ +- The reader's skip function is no longer ignored under `MPACK_OPTIMIZE_FOR_SIZE`. MPack v0.8.2 ------------ diff --git a/README.md b/README.md index 7997cf7..53b7338 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Introduction -MPack is a C implementation of an encoder and decoder for the [MessagePack](http://msgpack.org/) serialization format. It is intended to be: +MPack is a C implementation of an encoder and decoder for the [MessagePack](http://msgpack.org/) serialization format. It is: * Simple and easy to use * Secure against untrusted data @@ -10,7 +10,9 @@ MPack is a C implementation of an encoder and decoder for the [MessagePack](http The core of MPack contains a buffered reader and writer, and a tree-style parser that decodes into a tree of dynamically typed nodes. Helper functions can be enabled to read values of expected type, to work with files, to allocate strings automatically, to check UTF-8 encoding, and more. -The MPack code is small enough to be embedded directly into your codebase. The easiest way to use it is to download the [amalgamation package](https://github.com/ludocode/mpack/releases) and insert the source files directly into your project. Copy `mpack.h` and `mpack.c` into to your codebase, and copy `mpack-config.h.sample` as `mpack-config.h`. You can use the defaults or edit it if you'd like to customize the MPack featureset. +The MPack code is small enough to be embedded directly into your codebase. Simply download the [amalgamation package](https://github.com/ludocode/mpack/releases) and add `mpack.h` and `mpack.c` to your project. + +The MPack featureset can be customized at compile-time to set which features, components and debug checks are compiled, and what dependencies are available. ## Build Status @@ -30,14 +32,15 @@ MPack is beta software under development. | :-------: | :----------: | :----------: | | [Build Status][travis-mpack] | [Build Status][appveyor-mpack-develop] | [Build Status][coveralls-mpack-develop] | -## The Node Reader API +## The Node API The Node API parses a chunk of MessagePack data into an immutable tree of dynamically-typed nodes. A series of helper functions can be used to extract data of specific types from each node. ```C // parse a file into a node tree mpack_tree_t tree; -mpack_tree_init_file(&tree, "homepage-example.mp", 0); +mpack_tree_init_filename(&tree, "homepage-example.mp", 0); +mpack_tree_parse(&tree); mpack_node_t root = mpack_tree_root(&tree); // extract the example data on the msgpack homepage @@ -57,7 +60,7 @@ The above example decodes into allocated pages of nodes. A fixed node pool can b ## The Write API -The MPack Write API encodes structured data to MessagePack. +The Write API encodes structured data to MessagePack. ```C // encode to memory buffer diff --git a/docs/expect.md b/docs/expect.md index 1b1dfc0..5e9ea09 100644 --- a/docs/expect.md +++ b/docs/expect.md @@ -53,38 +53,38 @@ You can use [msgpack-tools](https://github.com/ludocode/msgpack-tools) with the int main(void) { - // initialize a reader from a file + // Initialize a reader from a file mpack_reader_t reader; mpack_reader_init_file(&reader, "example.mp"); - // the top-level array must have exactly three elements + // The top-level array must have exactly three elements mpack_expect_array_match(&reader, 3); - // the first two elements are short strings + // The first two elements are short strings char first[128]; char second[128]; mpack_expect_utf8_cstr(&reader, first, sizeof(first)); mpack_expect_utf8_cstr(&reader, second, sizeof(second)); - // next we have an array of up to ten ints + // Next we have an array of up to ten ints int32_t numbers[10]; size_t count = mpack_expect_array_max(&reader, sizeof(numbers) / sizeof(numbers[0])); for (size_t i = 0; i < count; ++i) numbers[i] = mpack_expect_i32(&reader); mpack_done_array(&reader); - // done reading the top-level array + // Done reading the top-level array mpack_done_array(&reader); - // clean up and handle errors + // Clean up and handle errors mpack_error_t error = mpack_reader_destroy(&reader); if (error != mpack_ok) { fprintf(stderr, "Error %i occurred reading data!\n", (int)error); return EXIT_FAILURE; } - // we now know the data was parsed correctly and can safely - // be used. the strings are null-terminated and valid UTF-8, + // We now know the data was parsed correctly and can safely + // be used. The strings are null-terminated and valid UTF-8, // the array contained at most ten elements, and the numbers // are all within the range of an int32_t. printf("%s\n", first); diff --git a/docs/features.md b/docs/features.md index fdf7bdf..400aabd 100644 --- a/docs/features.md +++ b/docs/features.md @@ -9,36 +9,42 @@ Feedback is welcome! Please let me know if any entries in the table are incorrec [mpack]: https://github.com/ludocode/mpack [msgpack-c]: https://github.com/msgpack/msgpack-c [cmp]: https://github.com/camgunz/cmp - -| | [MPack][mpack]
(v0.8) | [msgpack-c][msgpack-c]
(v1.3.0) | [CMP][cmp]
(v14) | -|:------------------------------------|:---:|:---:|:---:| -| No libc requirement | ✓ | | ✓ | -| No allocator requirement | ✓ | | ✓ | -| Growable memory writer | ✓ | ✓ | | -| File I/O helpers | ✓ | ✓ | | -| Tree parser | ✓ | ✓ | | -| Propagating errors | ✓ | | ✓ | -| Descriptive error information | | | | -| Compound size tracking | ✓ | | | -| Automatic compound size | | | | -| Incremental parser | ✓ | | ✓ | -| Incremental type helpers | ✓ | | ✓ | -| Incremental range/match helpers | ✓ | | | -| Asynchronous incremental parser | | | | -| Peek next element | ✓ | | | -| Tree stream parser | | ✓ | | -| Asynchronous tree stream parser | | ✓ | | -| Support for new (2.0) spec | ✓ | ✓ | ✓ | -| Compatible with older (1.0) spec | ✓ | ✓ | ✓ | -| UTF-8 verification | ✓ | | | -| Type-generic write helpers | ✓ | ✓ | | - -Most of the features above are optional when supported and can be configured in all libraries. In particular, UTF-8 verification is optional with MPack; compound size tracking is optional and disabled in release by default with MPack; and 1.0 (v4) spec compatibility is optional with CMP (v5/2.0 is the recommended and default usage.) +[cwpack]: https://github.com/clwi/CWPack + +| | [MPack][mpack]
(v1.0) | [msgpack-c][msgpack-c]
(v3.1.1) | [CMP][cmp]
(v18) | [CWPack][cwpack]
(v1.1) | +|:------------------------------------|:---:|:---:|:---:|:---:| +| No libc requirement | ✓ | | ✓ | ✓ | +| No allocator requirement | ✓ | | ✓ | ✓ | +| Growable memory writer | ✓ | ✓ | | ✓\* | +| File I/O helpers | ✓ | ✓ | | ✓\* | +| Tree parser | ✓ | ✓ | | | +| Propagating errors | ✓ | | ✓ | | +| Descriptive error information | | | | | +| Compound size tracking | ✓ | | | | +| Automatic compound size | | | | | +| Incremental parser | ✓ | | ✓ | ✓ | +| Typed read helpers | ✓ | | ✓ | | +| Range/match read helpers | ✓ | | | | +| Asynchronous incremental parser | | | | | +| Peek next element | ✓ | | | | +| Tree stream parser | ✓ | ✓ | | | +| Asynchronous tree stream parser | ✓ | ✓ | | | +| Support for new (2.0) spec | ✓ | ✓ | ✓ | ✓ | +| Compatible with older (1.0) spec | ✓ | ✓ | ✓ | ✓ | +| UTF-8 verification | ✓ | | | | +| Type-generic write helpers | ✓ | ✓ | | | +| Timestamps | ✓ | ✓ | | | + +Most of the features above are optional when supported and can be configured in all libraries. In particular, UTF-8 verification is optional with MPack; compound size tracking is optional and disabled in release by default with MPack; and 1.0 (v4) spec compatibility is optional in all libraries (v5/2.0 is the recommended and default usage.) + +\*CWPack's [goodies](https://github.com/clwi/CWPack/tree/master/goodies) are included in the above table. ## Glossary *Tree parsing* means parsing a MessagePack object into a DOM-style tree of dynamically-typed elements supporting random access. +*Incremental parsing* means being able to parse one basic MessagePack element at a time (either imperatively or with a SAX-style callback) with no per-element memory usage. + *Propagating errors* means a parse error or type error on one element places the whole parser, encoder or tree in an error state. This means you can check for errors only at certain key points rather than at every interaction with the library, and you get a final error state indicating whether any error occurred at any point during parsing or encoding. *Descriptive error information* means being able to get additional information when an error occurs, such as the tree position and byte position in the message where the error occurred. @@ -47,11 +53,9 @@ Most of the features above are optional when supported and can be configured in *Automatic compound size* means not having to specify the number of elements or bytes in an element up-front, instead determining it automatically when the element is closed. -*Incremental parsing* means being able to parse one basic MessagePack element at a time (either imperatively or with a SAX-style callback) with no per-element memory usage. - -*Incremental type helpers* means helper functions for an incremental parser that can check the expected type of an element. +*Typed read helpers* means helper functions for a parser that can check the expected type of an element and return its value in that type. For example `cmp_read_int()` in CMP or `mpack_expect_u32()` in MPack. -*Incremental range/match helpers* means helper functions for an incremental parser that can check not only the expected type of an element, but also enforce an allowed range or exact match on a given value. +*Range/match read helpers* means helper functions for a parser that can check not only the expected type of an element, but also enforce an allowed range or exact match on a given value. *Peeking the next element* means being able to view the next element during incremental parsing without popping it from the data buffer. diff --git a/src/mpack/mpack-common.h b/src/mpack/mpack-common.h index fa2d85c..d9d8e7e 100644 --- a/src/mpack/mpack-common.h +++ b/src/mpack/mpack-common.h @@ -49,8 +49,8 @@ MPACK_HEADER_START /* Version information */ -#define MPACK_VERSION_MAJOR 0 /**< The major version number of MPack. */ -#define MPACK_VERSION_MINOR 9 /**< The minor version number of MPack. */ +#define MPACK_VERSION_MAJOR 1 /**< The major version number of MPack. */ +#define MPACK_VERSION_MINOR 0 /**< The minor version number of MPack. */ #define MPACK_VERSION_PATCH 0 /**< The patch version number of MPack. */ /** A number containing the version number of MPack for comparison purposes. */ @@ -225,12 +225,13 @@ typedef struct mpack_timestamp_t { #endif /** - * An MPack tag is a MessagePack object header. It is a variant type representing - * any kind of object, and includes the value of that object when it is not a - * compound type (i.e. boolean, integer, float.) + * An MPack tag is a MessagePack object header. It is a variant type + * representing any kind of object, and includes the length of compound types + * (e.g. map, array, string) or the value of non-compound types (e.g. boolean, + * integer, float.) * - * If the type is compound (str, bin, ext, array or map), the embedded data is - * stored separately. + * If the type is compound (str, bin, ext, array or map), the contained + * elements or bytes are stored separately. * * This structure is opaque; its fields should not be accessed outside * of MPack. diff --git a/src/mpack/mpack-reader.h b/src/mpack/mpack-reader.h index cfa4136..50e7081 100644 --- a/src/mpack/mpack-reader.h +++ b/src/mpack/mpack-reader.h @@ -819,6 +819,8 @@ void mpack_discard(mpack_reader_t* reader); * @} */ +/** @cond */ + #if MPACK_DEBUG && MPACK_STDIO /** * @name Debugging Functions @@ -882,6 +884,8 @@ MPACK_INLINE void mpack_print(const char* data, size_t len) { */ #endif +/** @endcond */ + /** * @} */