This is an automated email from the git hooks/post-receive script. sebastic pushed a commit to branch master in repository protozero.
commit 90cfd8dffd222709c6461c1b049a73f978442218 Author: Bas Couwenberg <[email protected]> Date: Sat Jan 14 11:18:12 2017 +0100 Imported Upstream version 1.5.1 --- .travis.yml | 5 +-- CHANGELOG.md | 14 +++++++- CONTRIBUTING.md | 3 +- Makefile | 2 +- UPGRADING.md | 6 ++++ doc/advanced.md | 57 +++++++++++++++++++++++++++++-- include/protozero/byteswap.hpp | 2 +- include/protozero/pbf_builder.hpp | 2 +- include/protozero/pbf_reader.hpp | 4 +-- include/protozero/varint.hpp | 2 +- include/protozero/version.hpp | 5 ++- package.json | 2 +- test/t/tag_and_type/data-combined.pbf | 3 ++ test/t/tag_and_type/data-not-packed.pbf | 2 ++ test/t/tag_and_type/data-packed.pbf | 2 ++ test/t/tag_and_type/test_cases.cpp | 59 +++++++++++++++++++++++++++++++++ test/t/tag_and_type/testcase.cpp | 42 +++++++++++++++++++++++ test/t/tag_and_type/testcase.proto | 15 +++++++++ 18 files changed, 211 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 224d250..1035a0d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,7 +35,7 @@ addons_shortcuts: addons_gcc6: &gcc6 apt: sources: [ 'ubuntu-toolchain-r-test' ] - packages: [ 'g++-6', 'gcc-6', 'libprotobuf-dev','protobuf-compiler' ] + packages: [ 'g++-6', 'gcc-6', 'libprotobuf-dev','protobuf-compiler', 'doxygen', 'graphviz' ] matrix: include: @@ -86,7 +86,7 @@ matrix: addons: *gcc5 - os: linux compiler: "gcc-6" - env: CXX=g++-6 + env: CXX=g++-6 BUILD_DOC=1 addons: *gcc6 before_install: @@ -104,6 +104,7 @@ before_install: install: - make test + - if [ -n "${BUILD_DOC}" ]; then make doc; fi script: - if [ -n "${COVERAGE}" ]; then diff --git a/CHANGELOG.md b/CHANGELOG.md index 938fd4c..0c1acdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,17 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +## [1.5.1] - 2017-01-14 + +### Added + +- Better documentation for `tag_and_type()` in doc/advanced.md. + +### Fixed + +- Fixed broken "make doc" build. + + ## [1.5.0] - 2017-01-12 ### Added @@ -156,7 +167,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Make pbf reader and writer code endianess-aware. -[unreleased]: https://github.com/osmcode/libosmium/compare/v1.5.0...HEAD +[unreleased]: https://github.com/osmcode/libosmium/compare/v1.5.1...HEAD +[1.5.1]: https://github.com/osmcode/libosmium/compare/v1.5.0...v1.5.1 [1.5.0]: https://github.com/osmcode/libosmium/compare/v1.4.5...v1.5.0 [1.4.5]: https://github.com/osmcode/libosmium/compare/v1.4.4...v1.4.5 [1.4.4]: https://github.com/osmcode/libosmium/compare/v1.4.3...v1.4.4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 089e9d0..fae897b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,8 @@ To release a new protozero version: - - Make sure all tests are passing on travis and appveyor + - Make sure all tests are passing locally, on travis and on appveyor + - Make sure "make doc" builds - Update version number in - include/protozero/version.hpp (two places) - package.json diff --git a/Makefile b/Makefile index ec28029..5b6cf38 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ HPP_FILES := include/protozero/byteswap.hpp \ include/protozero/varint.hpp \ include/protozero/version.hpp -DOC_FILES = doc/cheatsheet.md doc/macros.md doc/tutorial.md +DOC_FILES = doc/advanced.md doc/cheatsheet.md doc/tutorial.md CFLAGS_PROTOBUF := $(subst -I,-isystem ,$(shell pkg-config protobuf --cflags)) LDFLAGS_PROTOBUF := $(shell pkg-config protobuf --libs-only-L) diff --git a/UPGRADING.md b/UPGRADING.md index 002ab99..7b34d8e 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -13,6 +13,12 @@ macro `PROTOZERO_STRICT_API` in which case Protozero will compile without the code used for backwards compatibilty. You will then get compile errors for older API usages. +## Upgrading from *v1.4.5* to *v1.5.0* + +* New functions for checking tag and type at the same time to make your + program more robust. Read the section "Repeated fields in messages" in + the new [Advanced Topics documentation](doc/advanced.md). + ## Upgrading from *v1.4.4* to *v1.4.5* * The macro `PROTOZERO_DO_NOT_USE_BARE_POINTER` is not used any more. If you diff --git a/doc/advanced.md b/doc/advanced.md index 8032bcb..fd98aca 100644 --- a/doc/advanced.md +++ b/doc/advanced.md @@ -33,13 +33,13 @@ If `protozero/version.hpp` is included, the following macros are set: The behaviour of Protozero can be changed by defining the following macros. They have to be set before including any of the Protozero headers. -## `PROTOZERO_STRICT_API` +### `PROTOZERO_STRICT_API` If this is set, you will get some extra warnings or errors during compilation if you are using an old (deprecated) interface to Protozero. Enable this if you want to make sure your code will work with future versions of Protozero. -## `PROTOZERO_USE_VIEW` +### `PROTOZERO_USE_VIEW` Protozero uses the class `protozero::data_view` as the return type of the `pbf_reader::get_view()` method and a few other functions take a @@ -71,6 +71,59 @@ not-packed) repeated fields with the same tag and their contents must be concatenated. It is your responsibility to do this, Protozero doesn't do that for you. +### Using `tag_and_type()` + +The `tag_and_type()` free function and the method of the same name on the +`pbf_reader` and `pbf_message` classes can be used to access both packed and +unpacked repeated fields. (It can also be used to check that you have the +right type of encoding for other fields.) + +Here is the outline: + +```cpp +enum class ExampleMsg : protozero::pbf_tag_type { + repeated_uint32_x = 1 +}; + +std::string data = ... +pbf_message<ExampleMsg> message{data}; +while (message.next()) { + switch (message.tag_and_type()) { + case tag_and_type(ExampleMsg::repeated_uint32_x, pbf_wire_type::length_delimited): { + auto xit = message.get_packed_uint32(); + ... // handle the repeated field when it is packed + } + break; + case tag_and_type(ExampleMsg::repeated_uint32_x, pbf_wire_type::varint): { + auto x = message.get_uint32(); + ... // handle the repeated field when it is not packed + } + break; + default: + message.skip(); + } +} +``` + +All this works on `pbf_reader` in the same way as with `pbf_message` with the +usual difference that `pbf_reader` takes a numeric field tag and `pbf_message` +an enum field. + +If you only want to check for one specific tag and type you can use the +two-argument version of `pbf_reader::next()`. In this case `17` is the field +tag we are looking for: + +```cpp +std::string data = ... +pbf_reader message{data}; +while (message.next(17, pbf_wire_type::varint)) { + auto foo = message.get_int32(); + ... +} +``` + +See the test under `test/t/tag_and_type/` for a complete example. + ## Reserving memory when writing messages diff --git a/include/protozero/byteswap.hpp b/include/protozero/byteswap.hpp index 3afb348..bca4844 100644 --- a/include/protozero/byteswap.hpp +++ b/include/protozero/byteswap.hpp @@ -16,8 +16,8 @@ documentation. * @brief Contains functions to swap bytes in values (for different endianness). */ -#include <cstdint> #include <cassert> +#include <cstdint> #include <protozero/config.hpp> diff --git a/include/protozero/pbf_builder.hpp b/include/protozero/pbf_builder.hpp index fef53e3..c40727c 100644 --- a/include/protozero/pbf_builder.hpp +++ b/include/protozero/pbf_builder.hpp @@ -18,8 +18,8 @@ documentation. #include <type_traits> -#include <protozero/types.hpp> #include <protozero/pbf_writer.hpp> +#include <protozero/types.hpp> namespace protozero { diff --git a/include/protozero/pbf_reader.hpp b/include/protozero/pbf_reader.hpp index ff4ccb9..98920fa 100644 --- a/include/protozero/pbf_reader.hpp +++ b/include/protozero/pbf_reader.hpp @@ -667,7 +667,7 @@ public: protozero_assert(tag() != 0 && "call next() before accessing field value"); protozero_assert(has_wire_type(pbf_wire_type::length_delimited) && "not of type string, bytes or message"); const auto len = get_len_and_skip(); - return data_view{m_data-len, len}; + return data_view{m_data - len, len}; } #ifndef PROTOZERO_STRICT_API @@ -683,7 +683,7 @@ public: protozero_assert(tag() != 0 && "call next() before accessing field value"); protozero_assert(has_wire_type(pbf_wire_type::length_delimited) && "not of type string, bytes or message"); const auto len = get_len_and_skip(); - return std::make_pair(m_data-len, len); + return std::make_pair(m_data - len, len); } #endif diff --git a/include/protozero/varint.hpp b/include/protozero/varint.hpp index 6d2a043..d115d5f 100644 --- a/include/protozero/varint.hpp +++ b/include/protozero/varint.hpp @@ -142,7 +142,7 @@ inline void skip_varint(const char** data, const char* end) { */ template <typename T> inline int write_varint(T data, uint64_t value) { - int n=1; + int n = 1; while (value >= 0x80) { *data++ = char((value & 0x7f) | 0x80); diff --git a/include/protozero/version.hpp b/include/protozero/version.hpp index b5da95b..9103bdc 100644 --- a/include/protozero/version.hpp +++ b/include/protozero/version.hpp @@ -23,13 +23,12 @@ documentation. #define PROTOZERO_VERSION_MINOR 5 /// The patch number -#define PROTOZERO_VERSION_PATCH 0 +#define PROTOZERO_VERSION_PATCH 1 /// The complete version number #define PROTOZERO_VERSION_CODE (PROTOZERO_VERSION_MAJOR * 10000 + PROTOZERO_VERSION_MINOR * 100 + PROTOZERO_VERSION_PATCH) /// Version number as string -#define PROTOZERO_VERSION_STRING "1.5.0" - +#define PROTOZERO_VERSION_STRING "1.5.1" #endif // PROTOZERO_VERSION_HPP diff --git a/package.json b/package.json index 38963cb..7e1b863 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "protozero", - "version": "1.5.0", + "version": "1.5.1", "description": "Minimalist protocol buffer decoder and encoder in C++", "main": "include_dirs.js", "repository" : { diff --git a/test/t/tag_and_type/data-combined.pbf b/test/t/tag_and_type/data-combined.pbf new file mode 100644 index 0000000..90a20f8 --- /dev/null +++ b/test/t/tag_and_type/data-combined.pbf @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/t/tag_and_type/data-not-packed.pbf b/test/t/tag_and_type/data-not-packed.pbf new file mode 100644 index 0000000..014f68d --- /dev/null +++ b/test/t/tag_and_type/data-not-packed.pbf @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/test/t/tag_and_type/data-packed.pbf b/test/t/tag_and_type/data-packed.pbf new file mode 100644 index 0000000..25a9dc1 --- /dev/null +++ b/test/t/tag_and_type/data-packed.pbf @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/test/t/tag_and_type/test_cases.cpp b/test/t/tag_and_type/test_cases.cpp new file mode 100644 index 0000000..3175388 --- /dev/null +++ b/test/t/tag_and_type/test_cases.cpp @@ -0,0 +1,59 @@ + +#include <vector> + +#include <test.hpp> + +enum class ExampleMsg : protozero::pbf_tag_type { + repeated_uint32_x = 1 +}; + +inline std::vector<uint32_t> read_data(const std::string& data) { + std::vector<uint32_t> values; + + protozero::pbf_message<ExampleMsg> message{data}; + while (message.next()) { + switch (message.tag_and_type()) { + case tag_and_type(ExampleMsg::repeated_uint32_x, protozero::pbf_wire_type::length_delimited): { + const auto xit = message.get_packed_uint32(); + for (const auto value : xit) { + values.push_back(value); + } + } + break; + case tag_and_type(ExampleMsg::repeated_uint32_x, protozero::pbf_wire_type::varint): { + const auto value = message.get_uint32(); + values.push_back(value); + } + break; + default: + message.skip(); + } + } + + return values; +} + +TEST_CASE("read not packed repeated field with tag_and_type") { + const auto values = read_data(load_data("tag_and_type/data-not-packed")); + + REQUIRE(values.size() == 3); + const std::vector<uint32_t> result{10, 11, 12}; + REQUIRE(values == result); +} + +TEST_CASE("read packed repeated field with tag_and_type") { + const auto values = read_data(load_data("tag_and_type/data-packed")); + + REQUIRE(values.size() == 3); + const std::vector<uint32_t> result{20, 21, 22}; + REQUIRE(values == result); +} + +TEST_CASE("read combined packed and not-packed repeated field with tag_and_type") { + const auto values = read_data(load_data("tag_and_type/data-combined")); + + REQUIRE(values.size() == 9); + const std::vector<uint32_t> result{10, 11, 12, 20, 21, 22, 30, 31, 32}; + REQUIRE(values == result); +} + diff --git a/test/t/tag_and_type/testcase.cpp b/test/t/tag_and_type/testcase.cpp new file mode 100644 index 0000000..fb6bcc8 --- /dev/null +++ b/test/t/tag_and_type/testcase.cpp @@ -0,0 +1,42 @@ + +#include <testcase.hpp> +#include "testcase.pb.h" + +int main(int c, char *argv[]) { + + std::string out; + + { + TestTagAndType::TestNotPacked msg; + for (uint32_t x = 10; x < 13; ++x) { + msg.add_x(x); + } + + out.append(write_to_file(msg, "data-not-packed.pbf")); + } + + { + TestTagAndType::TestPacked msg; + for (uint32_t x = 20; x < 23; ++x) { + msg.add_x(x); + } + + out.append(write_to_file(msg, "data-packed.pbf")); + } + + { + TestTagAndType::TestNotPacked msg; + for (uint32_t x = 30; x < 33; ++x) { + msg.add_x(x); + } + + std::string mout; + msg.SerializeToString(&mout); + out.append(mout); + } + + std::ofstream d("data-combined.pbf", std::ios_base::out|std::ios_base::binary); + assert(d.is_open()); + d << out; +} + diff --git a/test/t/tag_and_type/testcase.proto b/test/t/tag_and_type/testcase.proto new file mode 100644 index 0000000..bd31efc --- /dev/null +++ b/test/t/tag_and_type/testcase.proto @@ -0,0 +1,15 @@ + +option optimize_for = LITE_RUNTIME; + +package TestTagAndType; + +message TestNotPacked { + repeated int32 x = 1; + optional string s = 2; +} + +message TestPacked { + repeated int32 x = 1 [packed=true]; + optional string s = 2; +} + -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/protozero.git _______________________________________________ Pkg-grass-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

