[protozero] 01/06: Imported Upstream version 1.1.0

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Sat Aug 22 20:23:17 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository protozero.

commit 7773fddd2ed050f080b54a5a53ccb572afb61a57
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Sat Aug 22 22:06:52 2015 +0200

    Imported Upstream version 1.1.0
---
 .gitignore                                         |   4 +-
 CHANGELOG.md                                       |  25 +++
 Makefile                                           |  11 +-
 bench/data/README.md                               |  13 ++
 bench/data/enf-14-4824-6157.vector.pbf             | Bin 0 -> 494060 bytes
 .../data/mapbox-streets-v6-14-8714-8017.vector.pbf | Bin 0 -> 129144 bytes
 include/protozero/byteswap.hpp                     |  49 +++++
 include/protozero/pbf_builder.hpp                  | 111 ++++++++++
 include/protozero/pbf_message.hpp                  |  50 +++++
 include/protozero/pbf_reader.hpp                   | 232 +++++++++++++--------
 include/protozero/pbf_writer.hpp                   |  43 ++--
 include/protozero/varint.hpp                       |   4 -
 include/protozero/version.hpp                      |  22 ++
 test/include/test.hpp                              |   6 +-
 14 files changed, 454 insertions(+), 116 deletions(-)

diff --git a/.gitignore b/.gitignore
index 18430a8..ccd5ce5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,9 @@ coverage
 out
 protozero.Makefile
 tests.target.mk
-
+*.o
+*.gcno
+*.gcno
 #Visual Studio files and folders
 Release
 Debug
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..218d50b
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,25 @@
+
+# Change Log
+
+All notable changes to this project will be documented in this file.
+This project adheres to [Semantic Versioning](http://semver.org/).
+
+## [unreleased] -
+
+### Added
+
+### Changed
+
+### Fixed
+
+
+## [1.1.0] - 2015-08-22
+
+### Changed
+
+- Make pbf reader and writer code endianess-aware.
+
+
+[unreleased]: https://github.com/osmcode/libosmium/compare/v1.1.0...HEAD
+[1.1.0]: https://github.com/osmcode/libosmium/compare/v1.0.0...v1.1.0
+
diff --git a/Makefile b/Makefile
index fb1774a..c771dc9 100644
--- a/Makefile
+++ b/Makefile
@@ -13,8 +13,14 @@ COMMON_FLAGS := -fvisibility-inlines-hidden -std=c++11 $(WARNING_FLAGS)
 
 RELEASE_FLAGS := -O3 -DNDEBUG -march=native
 DEBUG_FLAGS := -O0 -g -fno-inline-functions
+PTHREAD_FLAGS =
 
 OS:=$(shell uname -s)
+
+ifeq ($(OS),Linux)
+    PTHREAD_FLAGS = -pthread
+endif
+
 ifeq ($(OS),Darwin)
     CXXFLAGS += -stdlib=libc++
     LDFLAGS += -stdlib=libc++
@@ -31,7 +37,8 @@ PROTO_FILES_CC := $(subst .proto,.pb.cc,$(PROTO_FILES))
 PROTO_FILES_H := $(subst .proto,.pb.h,$(PROTO_FILES))
 PROTO_FILES_O := $(subst .proto,.pb.o,$(PROTO_FILES))
 
-HPP_FILES := include/protozero/exception.hpp \
+HPP_FILES := include/protozero/byteswap.hpp \
+             include/protozero/exception.hpp \
              include/protozero/varint.hpp \
              include/protozero/pbf_types.hpp \
              include/protozero/pbf_reader.hpp \
@@ -64,7 +71,7 @@ all: ./test/tests test/writer_tests
 	$(CXX) -c -I. -Iinclude -Itest/include $(CXXFLAGS) $(COMMON_FLAGS) $(DEBUG_FLAGS) $< -o $@
 
 ./test/writer_tests: test/writer_tests.o $(PROTO_FILES_O) $(WRITER_TEST_CASES_O)
-	$(CXX) $(LDFLAGS) $(LDFLAGS_PROTOBUF) $^ -lprotobuf-lite -pthread -o $@
+	$(CXX) $(LDFLAGS) $(LDFLAGS_PROTOBUF) $^ -lprotobuf-lite $(PTHREAD_FLAGS) -o $@
 
 test: all
 	./test/tests
diff --git a/bench/data/README.md b/bench/data/README.md
new file mode 100644
index 0000000..202f94d
--- /dev/null
+++ b/bench/data/README.md
@@ -0,0 +1,13 @@
+
+
+mapbox-streets-v6/14/8714/8017.vector.pbf
+
+ - http://c.tile.openstreetmap.org/14/8714/8017.png
+ - https://a.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/14/8714/8017.vector.pbf
+ - https://www.mapbox.com/developers/vector-tiles/mapbox-streets/
+
+enf-14-4824-6157.vector.pbf
+
+ - enf.8k273nmi
+ - https://b.tiles.mapbox.com/v4/enf.c3a2de35/14/4824/6157@2x.png
+ - https://www.mapbox.com/blog/twitter-map-every-tweet/
\ No newline at end of file
diff --git a/bench/data/enf-14-4824-6157.vector.pbf b/bench/data/enf-14-4824-6157.vector.pbf
new file mode 100644
index 0000000..dcd8717
Binary files /dev/null and b/bench/data/enf-14-4824-6157.vector.pbf differ
diff --git a/bench/data/mapbox-streets-v6-14-8714-8017.vector.pbf b/bench/data/mapbox-streets-v6-14-8714-8017.vector.pbf
new file mode 100644
index 0000000..9553b22
Binary files /dev/null and b/bench/data/mapbox-streets-v6-14-8714-8017.vector.pbf differ
diff --git a/include/protozero/byteswap.hpp b/include/protozero/byteswap.hpp
new file mode 100644
index 0000000..d019c28
--- /dev/null
+++ b/include/protozero/byteswap.hpp
@@ -0,0 +1,49 @@
+#ifndef PROTOZERO_BYTESWAP_HPP
+#define PROTOZERO_BYTESWAP_HPP
+
+/*****************************************************************************
+
+protozero - Minimalistic protocol buffer decoder and encoder in C++.
+
+This file is from https://github.com/mapbox/protozero where you can find more
+documentation.
+
+*****************************************************************************/
+
+#include <cassert>
+
+namespace protozero {
+
+template <int N>
+inline void byteswap(const char* /*data*/, char* /*result*/) {
+    assert(false);
+}
+
+template <>
+inline void byteswap<1>(const char* data, char* result) {
+    result[0] = data[0];
+}
+
+template <>
+inline void byteswap<4>(const char* data, char* result) {
+    result[3] = data[0];
+    result[2] = data[1];
+    result[1] = data[2];
+    result[0] = data[3];
+}
+
+template <>
+inline void byteswap<8>(const char* data, char* result) {
+    result[7] = data[0];
+    result[6] = data[1];
+    result[5] = data[2];
+    result[4] = data[3];
+    result[3] = data[4];
+    result[2] = data[5];
+    result[1] = data[6];
+    result[0] = data[7];
+}
+
+} // end namespace protozero
+
+#endif // PROTOZERO_BYTESWAP_HPP
diff --git a/include/protozero/pbf_builder.hpp b/include/protozero/pbf_builder.hpp
new file mode 100644
index 0000000..d49a7ba
--- /dev/null
+++ b/include/protozero/pbf_builder.hpp
@@ -0,0 +1,111 @@
+#ifndef PROTOZERO_PBF_BUILDER_HPP
+#define PROTOZERO_PBF_BUILDER_HPP
+
+/*****************************************************************************
+
+protozero - Minimalistic protocol buffer decoder and encoder in C++.
+
+This file is from https://github.com/mapbox/protozero where you can find more
+documentation.
+
+*****************************************************************************/
+
+#include <type_traits>
+
+#include <protozero/pbf_types.hpp>
+#include <protozero/pbf_writer.hpp>
+
+namespace protozero {
+
+template <typename T>
+class pbf_builder : public pbf_writer {
+
+    static_assert(std::is_same<pbf_tag_type, typename std::underlying_type<T>::type>::value, "T must be enum with underlying type protozero::pbf_tag_type");
+
+public:
+
+    using enum_type = T;
+
+    pbf_builder(std::string& data) noexcept :
+        pbf_writer(data) {
+    }
+
+    template <typename P>
+    pbf_builder(pbf_writer& parent_writer, P tag) noexcept :
+        pbf_writer(parent_writer, pbf_tag_type(tag)) {
+    }
+
+#define PROTOZERO_WRITER_WRAP_ADD_SCALAR(name, type) \
+    inline void add_##name(T tag, type value) { \
+        pbf_writer::add_##name(pbf_tag_type(tag), value); \
+    }
+
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(bool, bool)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(enum, int32_t)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(int32, int32_t)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sint32, int32_t)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(uint32, uint32_t)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(int64, int64_t)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sint64, int64_t)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(uint64, uint64_t)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(fixed32, uint32_t)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sfixed32, int32_t)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(fixed64, uint64_t)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(sfixed64, int64_t)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(float, float)
+    PROTOZERO_WRITER_WRAP_ADD_SCALAR(double, double)
+
+    inline void add_bytes(T tag, const char* value, size_t size) {
+        pbf_writer::add_bytes(pbf_tag_type(tag), value, size);
+    }
+
+    inline void add_bytes(T tag, const std::string& value) {
+        pbf_writer::add_bytes(pbf_tag_type(tag), value);
+    }
+
+    inline void add_string(T tag, const char* value, size_t size) {
+        pbf_writer::add_string(pbf_tag_type(tag), value, size);
+    }
+
+    inline void add_string(T tag, const std::string& value) {
+        pbf_writer::add_string(pbf_tag_type(tag), value);
+    }
+
+    inline void add_string(T tag, const char* value) {
+        pbf_writer::add_string(pbf_tag_type(tag), value);
+    }
+
+    inline void add_message(T tag, const char* value, size_t size) {
+        pbf_writer::add_message(pbf_tag_type(tag), value, size);
+    }
+
+    inline void add_message(T tag, const std::string& value) {
+        pbf_writer::add_message(pbf_tag_type(tag), value);
+    }
+
+#define PROTOZERO_WRITER_WRAP_ADD_PACKED(name) \
+    template <typename InputIterator> \
+    inline void add_packed_##name(T tag, InputIterator first, InputIterator last) { \
+        pbf_writer::add_packed_##name(pbf_tag_type(tag), first, last); \
+    }
+
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(bool)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(enum)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(int32)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(sint32)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(uint32)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(int64)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(sint64)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(uint64)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(fixed32)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(sfixed32)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(fixed64)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(sfixed64)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(float)
+    PROTOZERO_WRITER_WRAP_ADD_PACKED(double)
+
+};
+
+} // end namespace protozero
+
+#endif // PROTOZERO_PBF_BUILDER_HPP
diff --git a/include/protozero/pbf_message.hpp b/include/protozero/pbf_message.hpp
new file mode 100644
index 0000000..af29a00
--- /dev/null
+++ b/include/protozero/pbf_message.hpp
@@ -0,0 +1,50 @@
+#ifndef PROTOZERO_PBF_MESSAGE_HPP
+#define PROTOZERO_PBF_MESSAGE_HPP
+
+/*****************************************************************************
+
+protozero - Minimalistic protocol buffer decoder and encoder in C++.
+
+This file is from https://github.com/mapbox/protozero where you can find more
+documentation.
+
+*****************************************************************************/
+
+#include <type_traits>
+
+#include <protozero/pbf_reader.hpp>
+#include <protozero/pbf_types.hpp>
+
+namespace protozero {
+
+template <typename T>
+class pbf_message : public pbf_reader {
+
+    static_assert(std::is_same<pbf_tag_type, typename std::underlying_type<T>::type>::value, "T must be enum with underlying type protozero::pbf_tag_type");
+
+public:
+
+    using enum_type = T;
+
+    template <typename... Args>
+    pbf_message(Args&&... args) noexcept :
+        pbf_reader(std::forward<Args>(args)...) {
+    }
+
+    inline bool next() {
+        return pbf_reader::next();
+    }
+
+    inline bool next(T tag) {
+        return pbf_reader::next(pbf_tag_type(tag));
+    }
+
+    inline T tag() const noexcept {
+        return T(pbf_reader::tag());
+    }
+
+};
+
+} // end namespace protozero
+
+#endif // PROTOZERO_PBF_MESSAGE_HPP
diff --git a/include/protozero/pbf_reader.hpp b/include/protozero/pbf_reader.hpp
index b9426d4..1c5ed0d 100644
--- a/include/protozero/pbf_reader.hpp
+++ b/include/protozero/pbf_reader.hpp
@@ -16,10 +16,6 @@ documentation.
  * @brief Contains the pbf_reader class.
  */
 
-#if __BYTE_ORDER != __LITTLE_ENDIAN
-# error "This code only works on little endian machines."
-#endif
-
 #include <cassert>
 #include <cstddef>
 #include <cstdint>
@@ -32,9 +28,13 @@ documentation.
 #include <protozero/exception.hpp>
 #include <protozero/varint.hpp>
 
+#if __BYTE_ORDER != __LITTLE_ENDIAN
+# include <protozero/byteswap.hpp>
+#endif
+
 /// Wrapper for assert() used for testing
-#ifndef pbf_assert
-# define pbf_assert(x) assert(x)
+#ifndef protozero_assert
+# define protozero_assert(x) assert(x)
 #endif
 
 namespace protozero {
@@ -77,10 +77,94 @@ class pbf_reader {
     // The tag of the current field.
     pbf_tag_type m_tag = 0;
 
-    template <typename T> inline T get_fixed();
+    template <typename T>
+    inline T get_fixed() {
+        T result;
+        skip_bytes(sizeof(T));
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+        memcpy(&result, m_data - sizeof(T), sizeof(T));
+#else
+        byteswap<sizeof(T)>(m_data - sizeof(T), reinterpret_cast<char*>(&result));
+#endif
+        return result;
+    }
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+    template <typename T>
+    inline std::pair<const T*, const T*> packed_fixed() {
+        protozero_assert(tag() != 0 && "call next() before accessing field value");
+        auto len = get_len_and_skip();
+        protozero_assert(len % sizeof(T) == 0);
+        return std::make_pair(reinterpret_cast<const T*>(m_data-len), reinterpret_cast<const T*>(m_data));
+    }
+
+#else
+
+    template <typename T>
+    class const_fixed_iterator : public std::iterator<std::forward_iterator_tag, T> {
+
+        const char* m_data;
+        const char* m_end;
+
+    public:
+
+        const_fixed_iterator() noexcept :
+            m_data(nullptr),
+            m_end(nullptr) {
+        }
+
+        const_fixed_iterator(const char *data, const char* end) noexcept :
+            m_data(data),
+            m_end(end) {
+        }
+
+        const_fixed_iterator(const const_fixed_iterator&) noexcept = default;
+        const_fixed_iterator(const_fixed_iterator&&) noexcept = default;
+
+        const_fixed_iterator& operator=(const const_fixed_iterator&) noexcept = default;
+        const_fixed_iterator& operator=(const_fixed_iterator&&) noexcept = default;
+
+        ~const_fixed_iterator() noexcept = default;
+
+        T operator*() {
+            T result;
+            byteswap<sizeof(T)>(m_data, reinterpret_cast<char*>(&result));
+            return result;
+        }
+
+        const_fixed_iterator& operator++() {
+            m_data += sizeof(T);
+            return *this;
+        }
+
+        const_fixed_iterator operator++(int) {
+            const const_fixed_iterator tmp(*this);
+            ++(*this);
+            return tmp;
+        }
+
+        bool operator==(const const_fixed_iterator& rhs) const noexcept {
+            return m_data == rhs.m_data && m_end == rhs.m_end;
+        }
+
+        bool operator!=(const const_fixed_iterator& rhs) const noexcept {
+            return !(*this == rhs);
+        }
+
+    }; // class const_fixed_iterator
+
+    template <typename T>
+    inline std::pair<const_fixed_iterator<T>, const_fixed_iterator<T>> packed_fixed() {
+        protozero_assert(tag() != 0 && "call next() before accessing field value");
+        auto len = get_len_and_skip();
+        protozero_assert(len % sizeof(T) == 0);
+        return std::make_pair(const_fixed_iterator<T>(m_data-len, m_data),
+                              const_fixed_iterator<T>(m_data, m_data));
+    }
+#endif
+
     template <typename T> inline T get_varint();
     template <typename T> inline T get_svarint();
-    template <typename T> inline std::pair<const T*, const T*> packed_fixed();
 
     inline pbf_length_type get_length() { return get_varint<pbf_length_type>(); }
 
@@ -273,7 +357,7 @@ public:
      * @post The current field was consumed and there is no current field now.
      */
     inline int32_t get_enum() {
-        pbf_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
+        protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
         return get_varint<int32_t>();
     }
 
@@ -285,7 +369,7 @@ public:
      * @post The current field was consumed and there is no current field now.
      */
     inline int32_t get_int32() {
-        pbf_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
+        protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
         return get_varint<int32_t>();
     }
 
@@ -297,7 +381,7 @@ public:
      * @post The current field was consumed and there is no current field now.
      */
     inline int32_t get_sint32() {
-        pbf_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
+        protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
         return get_svarint<int32_t>();
     }
 
@@ -309,7 +393,7 @@ public:
      * @post The current field was consumed and there is no current field now.
      */
     inline uint32_t get_uint32() {
-        pbf_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
+        protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
         return get_varint<uint32_t>();
     }
 
@@ -321,7 +405,7 @@ public:
      * @post The current field was consumed and there is no current field now.
      */
     inline int64_t get_int64() {
-        pbf_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
+        protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
         return get_varint<int64_t>();
     }
 
@@ -333,7 +417,7 @@ public:
      * @post The current field was consumed and there is no current field now.
      */
     inline int64_t get_sint64() {
-        pbf_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
+        protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
         return get_svarint<int64_t>();
     }
 
@@ -345,7 +429,7 @@ public:
      * @post The current field was consumed and there is no current field now.
      */
     inline uint64_t get_uint64() {
-        pbf_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
+        protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
         return get_varint<uint64_t>();
     }
 
@@ -671,7 +755,9 @@ public:
      * @pre The current field must be of type "repeated packed fixed32".
      * @post The current field was consumed and there is no current field now.
      */
-    inline std::pair<const uint32_t*, const uint32_t*> get_packed_fixed32();
+    inline auto get_packed_fixed32() -> decltype(packed_fixed<uint32_t>()) {
+        return packed_fixed<uint32_t>();
+    }
 
     /**
      * Consume current "repeated packed sfixed32" field.
@@ -682,7 +768,9 @@ public:
      * @pre The current field must be of type "repeated packed sfixed32".
      * @post The current field was consumed and there is no current field now.
      */
-    inline std::pair<const int32_t*, const int32_t*> get_packed_sfixed32();
+    inline auto get_packed_sfixed32() -> decltype(packed_fixed<int32_t>()) {
+        return packed_fixed<int32_t>();
+    }
 
     /**
      * Consume current "repeated packed fixed64" field.
@@ -693,7 +781,9 @@ public:
      * @pre The current field must be of type "repeated packed fixed64".
      * @post The current field was consumed and there is no current field now.
      */
-    inline std::pair<const uint64_t*, const uint64_t*> get_packed_fixed64();
+    inline auto get_packed_fixed64() -> decltype(packed_fixed<uint64_t>()) {
+        return packed_fixed<uint64_t>();
+    }
 
     /**
      * Consume current "repeated packed sfixed64" field.
@@ -704,7 +794,9 @@ public:
      * @pre The current field must be of type "repeated packed sfixed64".
      * @post The current field was consumed and there is no current field now.
      */
-    inline std::pair<const int64_t*, const int64_t*> get_packed_sfixed64();
+    inline auto get_packed_sfixed64() -> decltype(packed_fixed<int64_t>()) {
+        return packed_fixed<int64_t>();
+    }
 
     /**
      * Consume current "repeated packed float" field.
@@ -715,7 +807,9 @@ public:
      * @pre The current field must be of type "repeated packed float".
      * @post The current field was consumed and there is no current field now.
      */
-    inline std::pair<const float*, const float*> get_packed_float();
+    inline auto get_packed_float() -> decltype(packed_fixed<float>()) {
+        return packed_fixed<float>();
+    }
 
     /**
      * Consume current "repeated packed double" field.
@@ -726,7 +820,9 @@ public:
      * @pre The current field must be of type "repeated packed double".
      * @post The current field was consumed and there is no current field now.
      */
-    inline std::pair<const double*, const double*> get_packed_double();
+    inline auto get_packed_double() -> decltype(packed_fixed<double>()) {
+        return packed_fixed<double>();
+    }
 
     ///@}
 
@@ -767,11 +863,11 @@ bool pbf_reader::next() {
 
     // tags 0 and 19000 to 19999 are not allowed as per
     // https://developers.google.com/protocol-buffers/docs/proto
-    pbf_assert(((m_tag > 0 && m_tag < 19000) || (m_tag > 19999 && m_tag <= ((1 << 29) - 1))) && "tag out of range");
+    protozero_assert(((m_tag > 0 && m_tag < 19000) || (m_tag > 19999 && m_tag <= ((1 << 29) - 1))) && "tag out of range");
 
     m_wire_type = pbf_wire_type(value & 0x07);
 // XXX do we want this check? or should it throw an exception?
-//        pbf_assert((m_wire_type <=2 || m_wire_type == 5) && "illegal wire type");
+//        protozero_assert((m_wire_type <=2 || m_wire_type == 5) && "illegal wire type");
     return true;
 }
 
@@ -812,7 +908,7 @@ void pbf_reader::skip_bytes(pbf_length_type len) {
 }
 
 void pbf_reader::skip() {
-    pbf_assert(tag() != 0 && "call next() before calling skip()");
+    protozero_assert(tag() != 0 && "call next() before calling skip()");
     switch (wire_type()) {
         case pbf_wire_type::varint:
             (void)get_uint32(); // called for the side-effect of skipping value
@@ -844,65 +940,57 @@ T pbf_reader::get_varint() {
 
 template <typename T>
 T pbf_reader::get_svarint() {
-    pbf_assert((has_wire_type(pbf_wire_type::varint) || has_wire_type(pbf_wire_type::length_delimited)) && "not a varint");
+    protozero_assert((has_wire_type(pbf_wire_type::varint) || has_wire_type(pbf_wire_type::length_delimited)) && "not a varint");
     return static_cast<T>(decode_zigzag64(decode_varint(&m_data, m_end)));
 }
 
-template <typename T>
-T pbf_reader::get_fixed() {
-    T result;
-    skip_bytes(sizeof(T));
-    memcpy(&result, m_data - sizeof(T), sizeof(T));
-    return result;
-}
-
 uint32_t pbf_reader::get_fixed32() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
-    pbf_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
     return get_fixed<uint32_t>();
 }
 
 int32_t pbf_reader::get_sfixed32() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
-    pbf_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
     return get_fixed<int32_t>();
 }
 
 uint64_t pbf_reader::get_fixed64() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
-    pbf_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
     return get_fixed<uint64_t>();
 }
 
 int64_t pbf_reader::get_sfixed64() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
-    pbf_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
     return get_fixed<int64_t>();
 }
 
 float pbf_reader::get_float() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
-    pbf_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(has_wire_type(pbf_wire_type::fixed32) && "not a 32-bit fixed");
     return get_fixed<float>();
 }
 
 double pbf_reader::get_double() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
-    pbf_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(has_wire_type(pbf_wire_type::fixed64) && "not a 64-bit fixed");
     return get_fixed<double>();
 }
 
 bool pbf_reader::get_bool() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
-    pbf_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
-    pbf_assert((*m_data & 0x80) == 0 && "not a 1 byte varint");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
+    protozero_assert((*m_data & 0x80) == 0 && "not a 1 byte varint");
     skip_bytes(1);
     return m_data[-1] != 0; // -1 okay because we incremented m_data the line before
 }
 
 std::pair<const char*, pbf_length_type> pbf_reader::get_data() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
-    pbf_assert(has_wire_type(pbf_wire_type::length_delimited) && "not of type string, bytes or message");
+    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");
     auto len = get_len_and_skip();
     return std::make_pair(m_data-len, len);
 }
@@ -916,38 +1004,6 @@ std::string pbf_reader::get_string() {
     return get_bytes();
 }
 
-template <typename T>
-std::pair<const T*, const T*> pbf_reader::packed_fixed() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
-    auto len = get_len_and_skip();
-    pbf_assert(len % sizeof(T) == 0);
-    return std::make_pair(reinterpret_cast<const T*>(m_data-len), reinterpret_cast<const T*>(m_data));
-}
-
-std::pair<const uint32_t*, const uint32_t*> pbf_reader::get_packed_fixed32() {
-    return packed_fixed<uint32_t>();
-}
-
-std::pair<const uint64_t*, const uint64_t*> pbf_reader::get_packed_fixed64() {
-    return packed_fixed<uint64_t>();
-}
-
-std::pair<const int32_t*, const int32_t*> pbf_reader::get_packed_sfixed32() {
-    return packed_fixed<int32_t>();
-}
-
-std::pair<const int64_t*, const int64_t*> pbf_reader::get_packed_sfixed64() {
-    return packed_fixed<int64_t>();
-}
-
-std::pair<const float*, const float*> pbf_reader::get_packed_float() {
-    return packed_fixed<float>();
-}
-
-std::pair<const double*, const double*> pbf_reader::get_packed_double() {
-    return packed_fixed<double>();
-}
-
 std::pair<pbf_reader::const_bool_iterator, pbf_reader::const_bool_iterator> pbf_reader::get_packed_bool() {
     return get_packed_int32();
 }
@@ -957,42 +1013,42 @@ std::pair<pbf_reader::const_enum_iterator, pbf_reader::const_enum_iterator> pbf_
 }
 
 std::pair<pbf_reader::const_int32_iterator, pbf_reader::const_int32_iterator> pbf_reader::get_packed_int32() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
     auto len = get_len_and_skip();
     return std::make_pair(pbf_reader::const_int32_iterator(m_data-len, m_data),
                           pbf_reader::const_int32_iterator(m_data, m_data));
 }
 
 std::pair<pbf_reader::const_uint32_iterator, pbf_reader::const_uint32_iterator> pbf_reader::get_packed_uint32() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
     auto len = get_len_and_skip();
     return std::make_pair(pbf_reader::const_uint32_iterator(m_data-len, m_data),
                           pbf_reader::const_uint32_iterator(m_data, m_data));
 }
 
 std::pair<pbf_reader::const_sint32_iterator, pbf_reader::const_sint32_iterator> pbf_reader::get_packed_sint32() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
     auto len = get_len_and_skip();
     return std::make_pair(pbf_reader::const_sint32_iterator(m_data-len, m_data),
                           pbf_reader::const_sint32_iterator(m_data, m_data));
 }
 
 std::pair<pbf_reader::const_int64_iterator, pbf_reader::const_int64_iterator> pbf_reader::get_packed_int64() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
     auto len = get_len_and_skip();
     return std::make_pair(pbf_reader::const_int64_iterator(m_data-len, m_data),
                           pbf_reader::const_int64_iterator(m_data, m_data));
 }
 
 std::pair<pbf_reader::const_uint64_iterator, pbf_reader::const_uint64_iterator> pbf_reader::get_packed_uint64() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
     auto len = get_len_and_skip();
     return std::make_pair(pbf_reader::const_uint64_iterator(m_data-len, m_data),
                           pbf_reader::const_uint64_iterator(m_data, m_data));
 }
 
 std::pair<pbf_reader::const_sint64_iterator, pbf_reader::const_sint64_iterator> pbf_reader::get_packed_sint64() {
-    pbf_assert(tag() != 0 && "call next() before accessing field value");
+    protozero_assert(tag() != 0 && "call next() before accessing field value");
     auto len = get_len_and_skip();
     return std::make_pair(pbf_reader::const_sint64_iterator(m_data-len, m_data),
                           pbf_reader::const_sint64_iterator(m_data, m_data));
diff --git a/include/protozero/pbf_writer.hpp b/include/protozero/pbf_writer.hpp
index 14b0856..53cbfdf 100644
--- a/include/protozero/pbf_writer.hpp
+++ b/include/protozero/pbf_writer.hpp
@@ -16,23 +16,24 @@ documentation.
  * @brief Contains the pbf_writer class.
  */
 
-#if __BYTE_ORDER != __LITTLE_ENDIAN
-# error "This code only works on little endian machines."
-#endif
-
 #include <cassert>
 #include <cstddef>
 #include <cstdint>
 #include <cstring>
 #include <iterator>
+#include <limits>
 #include <string>
 
 #include <protozero/pbf_types.hpp>
 #include <protozero/varint.hpp>
 
+#if __BYTE_ORDER != __LITTLE_ENDIAN
+# include <protozero/byteswap.hpp>
+#endif
+
 /// Wrapper for assert() used for testing
-#ifndef pbf_assert
-# define pbf_assert(x) assert(x)
+#ifndef protozero_assert
+# define protozero_assert(x) assert(x)
 #endif
 
 namespace protozero {
@@ -50,13 +51,13 @@ class pbf_writer {
     size_t m_pos = 0;
 
     inline void add_varint(uint64_t value) {
-        pbf_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage");
-        pbf_assert(m_data);
+        protozero_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage");
+        protozero_assert(m_data);
         write_varint(std::back_inserter(*m_data), value);
     }
 
     inline void add_field(pbf_tag_type tag, pbf_wire_type type) {
-        pbf_assert(((tag > 0 && tag < 19000) || (tag > 19999 && tag <= ((1 << 29) - 1))) && "tag out of range");
+        protozero_assert(((tag > 0 && tag < 19000) || (tag > 19999 && tag <= ((1 << 29) - 1))) && "tag out of range");
         uint32_t b = (tag << 3) | uint32_t(type);
         add_varint(b);
     }
@@ -68,9 +69,15 @@ class pbf_writer {
 
     template <typename T>
     inline void add_fixed(T value) {
-        pbf_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage");
-        pbf_assert(m_data);
+        protozero_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage");
+        protozero_assert(m_data);
+#if __BYTE_ORDER == __LITTLE_ENDIAN
         m_data->append(reinterpret_cast<const char*>(&value), sizeof(T));
+#else
+        auto size = m_data->size();
+        m_data->resize(size + sizeof(T));
+        byteswap<sizeof(T)>(reinterpret_cast<const char*>(&value), const_cast<char*>(m_data->data() + size));
+#endif
     }
 
     template <typename T, typename It>
@@ -131,19 +138,19 @@ class pbf_writer {
     static const int reserve_bytes = sizeof(pbf_length_type) * 8 / 7 + 1;
 
     inline void open_submessage(pbf_tag_type tag) {
-        pbf_assert(m_pos == 0);
-        pbf_assert(m_data);
+        protozero_assert(m_pos == 0);
+        protozero_assert(m_data);
         add_field(tag, pbf_wire_type::length_delimited);
         m_data->append(size_t(reserve_bytes), '\0');
         m_pos = m_data->size();
     }
 
     inline void close_submessage() {
-        pbf_assert(m_pos != 0);
-        pbf_assert(m_data);
+        protozero_assert(m_pos != 0);
+        protozero_assert(m_data);
         auto length = pbf_length_type(m_data->size() - m_pos);
 
-        pbf_assert(m_data->size() >= m_pos - reserve_bytes);
+        protozero_assert(m_data->size() >= m_pos - reserve_bytes);
         auto n = write_varint(m_data->begin() + long(m_pos) - reserve_bytes, length);
 
         m_data->erase(m_data->begin() + long(m_pos) - reserve_bytes + n, m_data->begin() + long(m_pos));
@@ -369,8 +376,8 @@ public:
      * @param size Number of bytes to be written
      */
     inline void add_bytes(pbf_tag_type tag, const char* value, size_t size) {
-        pbf_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage");
-        pbf_assert(m_data);
+        protozero_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage");
+        protozero_assert(m_data);
         assert(size <= std::numeric_limits<pbf_length_type>::max());
         add_length_varint(tag, pbf_length_type(size));
         m_data->append(value, size);
diff --git a/include/protozero/varint.hpp b/include/protozero/varint.hpp
index bc9c329..27536fd 100644
--- a/include/protozero/varint.hpp
+++ b/include/protozero/varint.hpp
@@ -16,10 +16,6 @@ documentation.
  * @brief Contains low-level varint and zigzag encoding and decoding functions.
  */
 
-#if __BYTE_ORDER != __LITTLE_ENDIAN
-# error "This code only works on little endian machines."
-#endif
-
 #include <cstdint>
 
 #include <protozero/exception.hpp>
diff --git a/include/protozero/version.hpp b/include/protozero/version.hpp
new file mode 100644
index 0000000..098492e
--- /dev/null
+++ b/include/protozero/version.hpp
@@ -0,0 +1,22 @@
+#ifndef PROTOZERO_VERSION_HPP
+#define PROTOZERO_VERSION_HPP
+
+/*****************************************************************************
+
+protozero - Minimalistic protocol buffer decoder and encoder in C++.
+
+This file is from https://github.com/mapbox/protozero where you can find more
+documentation.
+
+*****************************************************************************/
+
+#define PROTOZERO_VERSION_MAJOR 1
+#define PROTOZERO_VERSION_MINOR 1
+#define PROTOZERO_VERSION_PATCH 0
+
+#define PROTOZERO_VERSION_CODE (PROTOZERO_VERSION_MAJOR * 10000 + PROTOZERO_VERSION_MINOR * 100 + PROTOZERO_VERSION_PATCH)
+
+#define PROTOZERO_VERSION_STRING "1.1.0"
+
+
+#endif // PROTOZERO_VERSION_HPP
diff --git a/test/include/test.hpp b/test/include/test.hpp
index a6a0b0c..33527a2 100644
--- a/test/include/test.hpp
+++ b/test/include/test.hpp
@@ -2,13 +2,13 @@
 #include <catch.hpp>
 
 #include <stdexcept>
-// Define pbf_assert() to throw this error. This allows the tests to check that
-// the assert fails.
+// Define protozero_assert() to throw this error. This allows the tests to
+// check that the assert fails.
 struct assert_error : public std::runtime_error {
     assert_error(const char* what_arg) : std::runtime_error(what_arg) {
     }
 };
-#define pbf_assert(x) if (!(x)) { throw(assert_error(#x)); }
+#define protozero_assert(x) if (!(x)) { throw(assert_error(#x)); }
 
 #include <protozero/pbf_reader.hpp>
 #include <protozero/pbf_writer.hpp>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/protozero.git



More information about the Pkg-grass-devel mailing list