[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