Updated bundled protozero to v1.7.0

This commit is contained in:
Denis Chaplygin 2020-10-16 10:25:52 +03:00
parent df3ed43d70
commit a8362d75b5
126 changed files with 18489 additions and 11079 deletions

View File

@ -1,4 +1,7 @@
# Unreleased
- Changes from 5.23.0
- Infrastructure
- CHANGED: Bundled protozero updated to v1.7.0. [#5858](https://github.com/Project-OSRM/osrm-backend/pull/5858)
# 5.23.0
- Changes from 5.22.0

View File

@ -1,14 +1,33 @@
---
Checks: '*,-cert-dcl21-cpp,-cert-err60-cpp,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-type-reinterpret-cast,-fuchsia-*,-google-runtime-references,-hicpp-no-array-decay'
Checks: '*,-bugprone-signed-char-misuse,-cert-dcl21-cpp,-cert-err58-cpp,-cert-err60-cpp,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-macro-usage,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-type-reinterpret-cast,-fuchsia-*,-google-runtime-references,-hicpp-avoid-c-arrays,-hicpp-no-array-decay,-hicpp-vararg,-modernize-avoid-c-arrays,-modernize-use-trailing-return-type,-readability-implicit-bool-conversion,-readability-magic-numbers'
#
# Disabled checks:
#
# bugprone-signed-char-misuse
# Lots of warnings in varint.hpp otherwise.
#
# cert-dcl21-cpp
# It is unclear whether this is still a good recommendation in modern C++.
#
# cert-err58-cpp
# Due to the Catch2 test framework.
#
# cert-err60-cpp
# Reports std::runtime_error as broken which we can't do anything about.
#
# cppcoreguidelines-avoid-c-arrays
# hicpp-avoid-c-arrays
# modernize-avoid-c-arrays
# Makes sense for some array, but especially for char arrays using
# std::array isn't a good solution.
#
# cppcoreguidelines-avoid-magic-numbers
# readability-magic-numbers
# Good idea, but it goes too far to force this everywhere.
#
# cppcoreguidelines-macro-usage
# There are cases where macros are simply needed.
#
# cppcoreguidelines-pro-bounds-array-to-pointer-decay
# Limited use and many false positives including for all asserts.
#
@ -28,6 +47,12 @@ Checks: '*,-cert-dcl21-cpp,-cert-err60-cpp,-cppcoreguidelines-pro-bounds-pointer
# hicpp-no-array-decay
# Limited use and many false positives including for all asserts.
#
# modernize-use-trailing-return-type
# We are not quite that modern.
#
# readability-implicit-bool-conversion
# Not necessarily more readable.
#
WarningsAsErrors: '*'
HeaderFilterRegex: '\/include\/'
AnalyzeTemporaryDtors: false

View File

@ -6,10 +6,6 @@
language: generic
sudo: false
dist: trusty
#-----------------------------------------------------------------------------
# Save common build configurations as shortcuts, so we can reference them later.
@ -17,147 +13,265 @@ addons_shortcuts:
addons_clang35: &clang35
apt:
sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-3.5' ]
packages: [ 'libprotobuf-dev','protobuf-compiler', 'clang-3.5' ]
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'clang-3.5' ]
addons_clang38: &clang38
apt:
sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-3.8' ]
packages: [ 'libprotobuf-dev','protobuf-compiler', 'clang-3.8' ]
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'clang-3.8' ]
addons_clang39: &clang39
apt:
sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-3.9' ]
packages: [ 'libprotobuf-dev','protobuf-compiler', 'clang-3.9' ]
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'clang-3.9' ]
addons_clang40: &clang40
apt:
sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-4.0' ]
packages: [ 'libprotobuf-dev','protobuf-compiler', 'clang-4.0' ]
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'clang-4.0' ]
addons_clang50: &clang50
apt:
sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-5.0' ]
packages: [ 'libprotobuf-dev','protobuf-compiler', 'clang-5.0', 'clang-tidy-5.0' ]
addons_gcc47: &gcc47
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'clang-5.0' ]
addons_clang60: &clang60
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libprotobuf-dev','protobuf-compiler', 'g++-4.7', 'gcc-4.7' ]
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'clang-6.0' ]
addons_clang7: &clang7
apt:
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'clang-7' ]
addons_clang8: &clang8
apt:
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'clang-8' ]
addons_clang9: &clang9
apt:
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'clang-9', 'clang-tidy-9' ]
addons_gcc48: &gcc48
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libprotobuf-dev','protobuf-compiler', 'g++-4.8', 'gcc-4.8' ]
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'g++-4.8', 'gcc-4.8' ]
addons_gcc49: &gcc49
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libprotobuf-dev','protobuf-compiler', 'g++-4.9', 'gcc-4.9' ]
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'g++-4.9', 'gcc-4.9' ]
addons_gcc5: &gcc5
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libprotobuf-dev','protobuf-compiler', 'g++-5', 'gcc-5' ]
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'g++-5', 'gcc-5' ]
addons_gcc6: &gcc6
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libprotobuf-dev','protobuf-compiler', 'g++-6', 'gcc-6' ]
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'g++-6', 'gcc-6' ]
addons_gcc7: &gcc7
apt:
packages: [ 'libprotobuf-dev', 'protobuf-compiler' ]
addons_gcc8: &gcc8
apt:
packages: [ 'libprotobuf-dev', 'protobuf-compiler', 'g++-8', 'gcc-8' ]
#-----------------------------------------------------------------------------
matrix:
jobs:
include:
- os: linux
dist: trusty
compiler: "clang-3.5"
env: BUILD='Debug' CC=clang-3.5 CXX=clang++-3.5
env: BUILD=Debug CC=clang-3.5 CXX=clang++-3.5
addons: *clang35
- os: linux
dist: xenial
compiler: "clang-3.8"
env: BUILD='Debug' CC=clang-3.8 CXX=clang++-3.8
env: BUILD=Debug CC=clang-3.8 CXX=clang++-3.8
addons: *clang38
- os: linux
dist: xenial
compiler: "clang-3.9"
env: BUILD='Debug' CC=clang-3.9 CXX=clang++-3.9
env: BUILD=Debug CC=clang-3.9 CXX=clang++-3.9
addons: *clang39
- os: linux
dist: xenial
compiler: "clang-4.0"
env: BUILD='Debug' CC=clang-4.0 CXX=clang++-4.0
env: BUILD=Debug CC=clang-4.0 CXX=clang++-4.0
addons: *clang40
- os: linux
dist: xenial
compiler: "clang-5.0"
env: BUILD='Debug' CC=clang-5.0 CXX=clang++-5.0
CLANG_TIDY=clang-tidy-5.0
env: BUILD=Debug CC=clang-5.0 CXX=clang++-5.0
addons: *clang50
- os: linux
compiler: "clang-5.0"
env: BUILD='Release' CC=clang-5.0 CXX=clang++-5.0
addons: *clang50
dist: xenial
compiler: "clang-6.0"
env: BUILD=Debug CC=clang-6.0 CXX=clang++-6.0
addons: *clang60
- os: linux
compiler: "clang-5.0"
env: BUILD='Debug' CC=clang-5.0 CXX=clang++-5.0
dist: bionic
compiler: "clang-7"
env: BUILD=Debug CC=clang-7 CXX=clang++-7
addons: *clang7
- os: linux
dist: bionic
compiler: "clang-8"
env: BUILD=Debug CC=clang-8 CXX=clang++-8
addons: *clang8
- os: linux
dist: bionic
compiler: "clang-9"
env: BUILD=Debug CC=clang-9 CXX=clang++-9
CLANG_TIDY=clang-tidy-9
addons: *clang9
- os: linux
dist: bionic
compiler: "clang-9"
env: BUILD=Debug CC=clang-9 CXX=clang++-9
CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer"
LDFLAGS="-fsanitize=address,undefined,integer"
# LSAN doesn't work on container-based system
sudo: required
addons: *clang50
addons: *clang9
- os: linux
compiler: "gcc-4.7"
env: BUILD='Debug' CC=gcc-4.7 CXX=g++-4.7
addons: *gcc47
dist: bionic
compiler: "clang-9"
env: BUILD=Release CC=clang-9 CXX=clang++-9
addons: *clang9
- os: linux
arch: arm64
dist: bionic
compiler: "clang-9"
env: BUILD=Debug CC=clang-9 CXX=clang++-9
CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer"
LDFLAGS="-fsanitize=address,undefined,integer"
addons: *clang9
- os: linux
arch: ppc64le
dist: bionic
compiler: "clang-9"
env: BUILD=Debug CC=clang-9 CXX=clang++-9
CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer"
LDFLAGS="-fsanitize=address,undefined,integer"
addons: *clang9
- os: linux
arch: s390x
dist: bionic
compiler: "clang-9"
env: BUILD=Debug CC=clang-9 CXX=clang++-9
CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer"
LDFLAGS="-fsanitize=address,undefined,integer"
addons: *clang9
- os: linux
dist: trusty
compiler: "gcc-4.8"
env: BUILD='Debug' CC=gcc-4.8 CXX=g++-4.8
env: BUILD=Debug CC=gcc-4.8 CXX=g++-4.8
addons: *gcc48
- os: linux
dist: trusty
compiler: "gcc-4.9"
env: BUILD='Debug' CC=gcc-4.9 CXX=g++-4.9
COVERAGE=gcov-4.9
CXXFLAGS="--coverage" LDFLAGS="--coverage"
env: BUILD=Debug CC=gcc-4.9 CXX=g++-4.9
addons: *gcc49
- os: linux
dist: trusty
compiler: "gcc-5"
env: BUILD='Debug' CC=gcc-5 CXX=g++-5
env: BUILD=Debug CC=gcc-5 CXX=g++-5
CXXFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0"
addons: *gcc5
- os: linux
dist: xenial
compiler: "gcc-5"
env: BUILD='Debug' CC=gcc-5 CXX=g++-5
env: BUILD=Debug CC=gcc-5 CXX=g++-5
CXXFLAGS="-D_GLIBCXX_USE_CXX11_ABI=1"
addons: *gcc5
- os: linux
dist: xenial
compiler: "gcc-6"
env: BUILD='Debug' CC=gcc-6 CXX=g++-6
env: BUILD=Debug CC=gcc-6 CXX=g++-6
addons: *gcc6
- os: linux
compiler: "gcc-6"
env: BUILD='Debug' CC=gcc-6 CXX=g++-6
PROTOZERO_DATA_VIEW=std::experimental::string_view
addons: *gcc6
dist: bionic
compiler: "gcc-7"
env: BUILD=Debug CC=gcc-7 CXX=g++-7
addons: *gcc7
- os: linux
compiler: "gcc-6"
env: BUILD='Release' CC=gcc-6 CXX=g++-6
addons: *gcc6
dist: bionic
compiler: "gcc-8"
env: BUILD=Debug CC=gcc-8 CXX=g++-8
addons: *gcc8
- os: linux
dist: bionic
compiler: "gcc-8"
env: BUILD=Debug CC=gcc-8 CXX=g++-8
COVERAGE=gcov-8
CXXFLAGS="--coverage" LDFLAGS="--coverage"
addons: *gcc8
- os: linux
dist: bionic
compiler: "gcc-8"
env: BUILD=Debug CC=gcc-8 CXX=g++-8
PROTOZERO_DATA_VIEW=std::string_view
addons: *gcc8
- os: linux
dist: bionic
compiler: "gcc-8"
env: BUILD=Release CC=gcc-8 CXX=g++-8
addons: *gcc8
- os: linux
arch: arm64
dist: bionic
compiler: "gcc-8"
env: BUILD=Debug CC=gcc-8 CXX=g++-8
addons: *gcc8
- os: linux
arch: ppc64le
dist: bionic
compiler: "gcc-8"
env: BUILD=Debug CC=gcc-8 CXX=g++-8
addons: *gcc8
- os: linux
arch: s390x
dist: bionic
compiler: "gcc-8"
env: BUILD=Debug CC=gcc-8 CXX=g++-8
addons: *gcc8
- os: osx
osx_image: xcode6.4
osx_image: xcode9.4
compiler: clang
env: BUILD='Debug'
env: BUILD=Debug
- os: osx
osx_image: xcode7.3
osx_image: xcode10.3
compiler: clang
env: BUILD='Debug'
env: BUILD=Debug
- os: osx
osx_image: xcode8.3
osx_image: xcode11.4
compiler: clang
env: BUILD='Debug'
env: BUILD=Debug
- os: osx
osx_image: xcode9.1
osx_image: xcode11.4
compiler: clang
env: BUILD='Debug'
- os: osx
osx_image: xcode9.1
compiler: clang
env: BUILD='Release'
env: BUILD=Release
#-----------------------------------------------------------------------------
install:
- if [[ $(uname -s) == 'Darwin' ]]; then
brew update;
brew install protobuf;
fi
script:
- mkdir build
- cd build

View File

@ -5,7 +5,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
This project adheres to [Semantic Versioning](http://semver.org/).
## [unreleased] -
### Added
@ -15,6 +14,87 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
## [1.7.0] - 2020-06-08
### Added
- Support for buffer types other that `std::string`. `pbf_writer` is now
just a typedef for `basic_pbf_writer<std::string>`. Other buffer types
can be used with `basic_pbf_writer`. See `doc/advanced.md` for details.
### Changed
- Switched to *catch2* for testing.
- Some minor tweaks.
### Fixed
- Removed some undefined behaviour.
## [1.6.8] - 2019-08-15
### Changed
- Various code cleanups due to clang-tidy warnings.
### Fixed
- Made `data_view::compare` noexcept.
## [1.6.7] - 2018-02-21
### Fixed
- Signed-unsigned comparison on 32 bit systems.
## [1.6.6] - 2018-02-20
### Fixed
- Fixed several place with possible undefined behaviour.
## [1.6.5] - 2018-02-05
### Fixed
- Avoid UB: Do not calculate pointer outside array bounds.
- Specify proto2 syntax in .proto files to appease protoc.
## [1.6.4] - 2018-11-08
### Added
- Add function `data()` to get the not yet read data from a `pbf_reader`.
- New `add_packed_fixed()` template function for `pbf_writer`.
- New `length_of_varint()` helper function calculates how long a varint
would be for a specified value.
### Changed
- More consistent implementation of operators as free friend functions.
### Fixed
- Fixed some zigzag encoding tests on MSVC.
- Add extra cast so we do an xor with unsigned ints.
- No more bitwise operations on signed integers in varint decoder.
- No more bitwise operations on signed integers in zigzag encoder/decoder.
## [1.6.3] - 2018-07-17
### Changed
- Moved `byteswap_inplace` functions from detail into protozero namespace.
They can be useful outsize protozero.
- More asserts and unit tests and small cleanups.
## [1.6.2] - 2018-03-09
### Changed
@ -301,7 +381,14 @@ 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.6.2...HEAD
[unreleased]: https://github.com/osmcode/libosmium/compare/v1.7.0...HEAD
[1.7.0]: https://github.com/osmcode/libosmium/compare/v1.6.8...v1.7.0
[1.6.8]: https://github.com/osmcode/libosmium/compare/v1.6.7...v1.6.8
[1.6.7]: https://github.com/osmcode/libosmium/compare/v1.6.6...v1.6.7
[1.6.6]: https://github.com/osmcode/libosmium/compare/v1.6.5...v1.6.6
[1.6.5]: https://github.com/osmcode/libosmium/compare/v1.6.4...v1.6.5
[1.6.4]: https://github.com/osmcode/libosmium/compare/v1.6.3...v1.6.4
[1.6.3]: https://github.com/osmcode/libosmium/compare/v1.6.2...v1.6.3
[1.6.2]: https://github.com/osmcode/libosmium/compare/v1.6.1...v1.6.2
[1.6.1]: https://github.com/osmcode/libosmium/compare/v1.6.0...v1.6.1
[1.6.0]: https://github.com/osmcode/libosmium/compare/v1.5.3...v1.6.0

View File

@ -13,8 +13,8 @@ cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(protozero)
set(PROTOZERO_VERSION_MAJOR 1)
set(PROTOZERO_VERSION_MINOR 6)
set(PROTOZERO_VERSION_PATCH 2)
set(PROTOZERO_VERSION_MINOR 7)
set(PROTOZERO_VERSION_PATCH 0)
set(PROTOZERO_VERSION
"${PROTOZERO_VERSION_MAJOR}.${PROTOZERO_VERSION_MINOR}.${PROTOZERO_VERSION_PATCH}")
@ -26,7 +26,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
option(WERROR "Add -Werror flag to build (turns warnings into errors)" ON)
if(MSVC)
add_definitions(-std=c++11 /W3)
add_definitions(/W3)
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS)
else()
add_definitions(-std=c++11 -Wall -Wextra -pedantic -Wsign-compare -Wunused-parameter -Wno-float-equal -Wno-covered-switch-default)
@ -58,7 +58,7 @@ find_package(Protobuf)
#
#-----------------------------------------------------------------------------
message(STATUS "Looking for clang-tidy")
find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-6.0 clang-tidy-5.0)
find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-10 clang-tidy-9 clang-tidy-8 clang-tidy-7 clang-tidy-6.0 clang-tidy-5.0)
if(CLANG_TIDY)
message(STATUS "Looking for clang-tidy - found ${CLANG_TIDY}")
@ -66,7 +66,8 @@ if(CLANG_TIDY)
${CLANG_TIDY}
-p ${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/test/*.cpp
${CMAKE_SOURCE_DIR}/test/t/*/*.cpp
${CMAKE_SOURCE_DIR}/test/t/*/reader_test_cases.cpp
${CMAKE_SOURCE_DIR}/test/t/*/writer_test_cases.cpp
${CMAKE_SOURCE_DIR}/test/unit/*.cpp
${CMAKE_SOURCE_DIR}/tools/*.cpp
)

View File

@ -56,9 +56,9 @@ You have to have a working knowledge of how
* Read the [upgrading instructions](UPGRADING.md) if you are upgrading from
an older version of Protozero.
The build process will also build the Doxygen-based reference documentation
if you have [Doxygen](http://www.stack.nl/~dimitri/doxygen/) installed. Then
open `doc/html/index.html` in your browser to read it.
The build process will also build the Doxygen-based reference documentation if
you have Doxygen installed. Then open `doc/html/index.html` in your browser to
read it.
## Endianness

View File

@ -13,6 +13,11 @@ 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.6* to *v1.7*
* The `pbf_writer` class is now a typedef for `basic_pbf_writer<std::string>`
If you have forward declared it in your code, it might have to change.
## Upgrading from *v1.5* to *v1.6.0*
* The `data_view` class moved from `types.hpp` into its own header file

View File

@ -24,6 +24,9 @@ environment:
autocrlf: false
- config: RelWithDebInfo
autocrlf: false
- config: Debug
autocrlf: false
platform: x86
#-----------------------------------------------------------------------------
@ -36,22 +39,32 @@ init:
# halts: "msys2-runtime and catgets are in conflict. Remove catgets?"
# See also: https://github.com/Alexpux/MSYS2-packages/issues/1141
install:
- if [%config%]==[MSYS2] (
C:\msys64\usr\bin\pacman --noconfirm --sync --refresh --refresh --sysupgrade --sysupgrade --ask=20
&& C:\msys64\usr\bin\pacman -Rc --noconfirm mingw-w64-x86_64-gcc-libs
- if "%config%"=="MSYS2" (
set "PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH%" &&
pacman --noconfirm --sync --refresh --refresh --sysupgrade --sysupgrade --ask=20 &&
pacman -Rc --noconfirm mingw-w64-x86_64-gcc-libs &&
pacman -S --needed --noconfirm mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-doxygen mingw-w64-x86_64-protobuf
)
build_script:
- if [%config%]==[MSYS2] (
build-msys2.bat
- cd c:\projects\protozero
- mkdir build
- cd build
- if "%platform%"=="x64" (
set vcvarsall_arg=amd64
) else (
build-appveyor.bat
set vcvarsall_arg=x86
)
- if "%config%"=="MSYS2" (
cmake .. -LA -G "MSYS Makefiles" &&
make VERBOSE=1
) else (
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall" %vcvarsall_arg% &&
cmake .. -LA -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=%config% &&
nmake VERBOSE=1
)
# remove garbage VS messages
# http://help.appveyor.com/discussions/problems/4569-the-target-_convertpdbfiles-listed-in-a-beforetargets-attribute-at-c-does-not-exist-in-the-project-and-will-be-ignored
before_build:
- del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
test_script:
- ctest --output-on-failure
#-----------------------------------------------------------------------------

View File

@ -1,65 +0,0 @@
@ECHO OFF
SETLOCAL
SET EL=0
ECHO ~~~~~~ %~f0 ~~~~~~
::show all available env vars
SET
ECHO cmake on AppVeyor
cmake -version
ECHO activating VS cmd prompt && CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET protobuf_sdk=protozero-dep-protobuf-2.6.1.7z
IF EXIST %protobuf_sdk% (ECHO protobuf already downloaded) ELSE (ECHO downloading protobuf ... && powershell Invoke-WebRequest https://mapbox.s3.amazonaws.com/windows-builds/windows-build-deps/$env:protobuf_sdk -OutFile $pwd\$env:protobuf_sdk)
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
IF EXIST deps\protobuf (ECHO protobuf already extracted) ELSE (CALL 7z x -y %protobuf_sdk% | %windir%\system32\FIND "ing archive")
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET PATH=%~dp0deps\protobuf;%PATH%
IF EXIST build ECHO deleting build dir... && RD /Q /S build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
MKDIR build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
CD build
ECHO config^: %config%
::This will produce lots of LNK4099 warnings which can be ignored.
::Unfortunately they can't be disabled, see
::http://stackoverflow.com/questions/661606/visual-c-how-to-disable-specific-linker-warnings
SET CMAKE_CMD=cmake .. ^
-LA -G "Visual Studio 14 Win64"
ECHO calling^: %CMAKE_CMD%
%CMAKE_CMD%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET avlogger=
IF /I "%APPVEYOR%"=="True" SET avlogger=/logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
msbuild protozero.sln ^
/p:Configuration=%config% ^
/toolsversion:14.0 ^
/p:Platform=x64 ^
/p:PlatformToolset=v140 %avlogger%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ctest --output-on-failure ^
-C %config% ^
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
GOTO DONE
:ERROR
ECHO ~~~~~~ ERROR %~f0 ~~~~~~
SET EL=%ERRORLEVEL%
:DONE
IF %EL% NEQ 0 ECHO. && ECHO !!! ERRORLEVEL^: %EL% !!! && ECHO.
ECHO ~~~~~~ DONE %~f0 ~~~~~~
EXIT /b %EL%

View File

@ -1,29 +0,0 @@
@ECHO OFF
SETLOCAL
SET EL=0
ECHO =========== %~f0 ===========
SET VERBOSITY_MSBUILD=diagnostic
IF NOT "%1"=="" SET VERBOSITY_MSBUILD=%1
SET platform=x64
SET configuration=Release
CALL build-appveyor.bat %VERBOSITY_MSBUILD%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET platform=x86
SET configuration=Debug
CALL build-appveyor.bat %VERBOSITY_MSBUILD%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
GOTO DONE
:ERROR
ECHO =========== ERROR %~f0 ===========
ECHO ERRORLEVEL^: %ERRORLEVEL%
SET EL=%ERRORLEVEL%
:DONE
ECHO =========== DONE %~f0 ===========
EXIT /b %EL%

View File

@ -1,18 +0,0 @@
echo "Adding MSYS2 to path..."
SET "PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH%"
echo %PATH%
echo "Installing MSYS2 packages..."
bash -lc "pacman -S --needed --noconfirm mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-doxygen mingw-w64-x86_64-protobuf"
echo "Generating makefiles"
mkdir build
cd build
cmake .. -LA -G "MSYS Makefiles"
echo "Building"
make VERBOSE=1
echo "Testing"
ctest --output-on-failure

View File

@ -2046,7 +2046,7 @@ EXTERNAL_PAGES = YES
# interpreter (i.e. the result of 'which perl').
# The default file (with absolute path) is: /usr/bin/perl.
PERL_PATH = /usr/bin/perl
#PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
@ -2068,7 +2068,7 @@ CLASS_DIAGRAMS = YES
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
#MSCGEN_PATH =
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The

View File

@ -269,3 +269,58 @@ still considerably cheaper than decoding the varints. You have to benchmark
your use case to see whether the `reserve()` (or whatever you are using the
`size()` for) is worth it.
## Using a different buffer class than std::string
Normally you are using the `pbf_writer` or `pbf_builder` classes which use a
`std::string` that you supply as their buffer for building the actual protocol
buffers message into. But you can use a different buffer implementation
instead. This might be useful if you want to use a fixed-size buffer for
instance.
The `pbf_writer` and `pbf_builder` classes are actually only aliases for the
`basic_pbf_writer` and `basic_pbf_builder` template classes:
```cpp
using pbf_writer = basic_pbf_writer<std::string>;
template <typename T>
using pbf_builder = basic_pbf_builder<std::string, T>;
```
If you want to use a different buffer type, use the `basic_*` form of the
class and use the buffer class as template parameter. When instantiating the
`basic_pbf_writer` or `basic_pbf_builder`, the only parameter to the
constructor must always be a reference to an object of the buffer class.
```cpp
some_buffer_class buffer;
basic_pbf_writer<some_buffer_class> writer{buffer};
```
For this to work you must supply template specializations for some static
functions in the `protozero::buffer_customization` struct, see
`buffer_tmpl.hpp` for details.
Protozero already supports two buffer types:
* `std::string` (to use include `protozero/buffer_string.hpp`)
* `std::vector<char>` (to use include `protozero/buffer_vector.hpp`)
There is a class `protozero::fixed_size_buffer_adaptor` you can use as adaptor
for any fixed-sized buffer you might have. Include `protozero/buffer_fixed.hpp`
to use it:
```cpp
#include <protozero/buffer_fixed.hpp>
your_buffer_class some_buffer;
protozero::fixed_size_buffer_adaptor buffer_adaptor{some_buffer.data(), some_buffer.size()};
basic_pbf_writer<protozero::fixed_size_buffer_adaptor> writer{buffer_adaptor};
```
The buffer adaptor can be initialized with any container if it supports the
`data()` and `size()` member functions:
```cpp
protozero::fixed_size_buffer_adaptor buffer_adaptor{some_buffer};
```

View File

@ -0,0 +1,266 @@
#ifndef PROTOZERO_BASIC_PBF_BUILDER_HPP
#define PROTOZERO_BASIC_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.
*****************************************************************************/
/**
* @file basic_pbf_builder.hpp
*
* @brief Contains the basic_pbf_builder template class.
*/
#include "basic_pbf_writer.hpp"
#include "types.hpp"
#include <type_traits>
namespace protozero {
/**
* The basic_pbf_builder is used to write PBF formatted messages into a buffer.
* It is based on the basic_pbf_writer class and has all the same methods. The
* difference is that while the pbf_writer class takes an integer tag,
* this template class takes a tag of the template type T. The idea is that
* T will be an enumeration value and this helps reduce the possibility of
* programming errors.
*
* Almost all methods in this class can throw an std::bad_alloc exception if
* the underlying buffer class wants to resize.
*
* Read the tutorial to understand how this class is used. In most cases you
* want to use the pbf_builder class which uses a std::string as buffer type.
*/
template <typename TBuffer, typename T>
class basic_pbf_builder : public basic_pbf_writer<TBuffer> {
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:
/// The type of messages this class will build.
using enum_type = T;
basic_pbf_builder() = default;
/**
* Create a builder using the given string as a data store. The object
* stores a reference to that string and adds all data to it. The string
* doesn't have to be empty. The pbf_message object will just append data.
*/
explicit basic_pbf_builder(TBuffer& data) noexcept :
basic_pbf_writer<TBuffer>{data} {
}
/**
* Construct a pbf_builder for a submessage from the pbf_message or
* pbf_writer of the parent message.
*
* @param parent_writer The parent pbf_message or pbf_writer
* @param tag Tag of the field that will be written
*/
template <typename P>
basic_pbf_builder(basic_pbf_writer<TBuffer>& parent_writer, P tag) noexcept :
basic_pbf_writer<TBuffer>{parent_writer, pbf_tag_type(tag)} {
}
/// @cond INTERNAL
#define PROTOZERO_WRITER_WRAP_ADD_SCALAR(name, type) \
void add_##name(T tag, type value) { \
basic_pbf_writer<TBuffer>::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)
#undef PROTOZERO_WRITER_WRAP_ADD_SCALAR
/// @endcond
/**
* Add "bytes" field to data.
*
* @param tag Tag of the field
* @param value Pointer to value to be written
* @param size Number of bytes to be written
*/
void add_bytes(T tag, const char* value, std::size_t size) {
basic_pbf_writer<TBuffer>::add_bytes(pbf_tag_type(tag), value, size);
}
/**
* Add "bytes" field to data.
*
* @param tag Tag of the field
* @param value Value to be written
*/
void add_bytes(T tag, const data_view& value) {
basic_pbf_writer<TBuffer>::add_bytes(pbf_tag_type(tag), value);
}
/**
* Add "bytes" field to data.
*
* @param tag Tag of the field
* @param value Value to be written
*/
void add_bytes(T tag, const std::string& value) {
basic_pbf_writer<TBuffer>::add_bytes(pbf_tag_type(tag), value);
}
/**
* Add "bytes" field to data. Bytes from the value are written until
* a null byte is encountered. The null byte is not added.
*
* @param tag Tag of the field
* @param value Pointer to zero-delimited value to be written
*/
void add_bytes(T tag, const char* value) {
basic_pbf_writer<TBuffer>::add_bytes(pbf_tag_type(tag), value);
}
/**
* Add "bytes" field to data using vectored input. All the data in the
* 2nd and further arguments is "concatenated" with only a single copy
* into the final buffer.
*
* This will work with objects of any type supporting the data() and
* size() methods like std::string or protozero::data_view.
*
* Example:
* @code
* std::string data1 = "abc";
* std::string data2 = "xyz";
* builder.add_bytes_vectored(1, data1, data2);
* @endcode
*
* @tparam Ts List of types supporting data() and size() methods.
* @param tag Tag of the field
* @param values List of objects of types Ts with data to be appended.
*/
template <typename... Ts>
void add_bytes_vectored(T tag, Ts&&... values) {
basic_pbf_writer<TBuffer>::add_bytes_vectored(pbf_tag_type(tag), std::forward<Ts>(values)...);
}
/**
* Add "string" field to data.
*
* @param tag Tag of the field
* @param value Pointer to value to be written
* @param size Number of bytes to be written
*/
void add_string(T tag, const char* value, std::size_t size) {
basic_pbf_writer<TBuffer>::add_string(pbf_tag_type(tag), value, size);
}
/**
* Add "string" field to data.
*
* @param tag Tag of the field
* @param value Value to be written
*/
void add_string(T tag, const data_view& value) {
basic_pbf_writer<TBuffer>::add_string(pbf_tag_type(tag), value);
}
/**
* Add "string" field to data.
*
* @param tag Tag of the field
* @param value Value to be written
*/
void add_string(T tag, const std::string& value) {
basic_pbf_writer<TBuffer>::add_string(pbf_tag_type(tag), value);
}
/**
* Add "string" field to data. Bytes from the value are written until
* a null byte is encountered. The null byte is not added.
*
* @param tag Tag of the field
* @param value Pointer to value to be written
*/
void add_string(T tag, const char* value) {
basic_pbf_writer<TBuffer>::add_string(pbf_tag_type(tag), value);
}
/**
* Add "message" field to data.
*
* @param tag Tag of the field
* @param value Pointer to message to be written
* @param size Length of the message
*/
void add_message(T tag, const char* value, std::size_t size) {
basic_pbf_writer<TBuffer>::add_message(pbf_tag_type(tag), value, size);
}
/**
* Add "message" field to data.
*
* @param tag Tag of the field
* @param value Value to be written. The value must be a complete message.
*/
void add_message(T tag, const data_view& value) {
basic_pbf_writer<TBuffer>::add_message(pbf_tag_type(tag), value);
}
/**
* Add "message" field to data.
*
* @param tag Tag of the field
* @param value Value to be written. The value must be a complete message.
*/
void add_message(T tag, const std::string& value) {
basic_pbf_writer<TBuffer>::add_message(pbf_tag_type(tag), value);
}
/// @cond INTERNAL
#define PROTOZERO_WRITER_WRAP_ADD_PACKED(name) \
template <typename InputIterator> \
void add_packed_##name(T tag, InputIterator first, InputIterator last) { \
basic_pbf_writer<TBuffer>::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)
#undef PROTOZERO_WRITER_WRAP_ADD_PACKED
/// @endcond
}; // class basic_pbf_builder
} // end namespace protozero
#endif // PROTOZERO_BASIC_PBF_BUILDER_HPP

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,222 @@
#ifndef PROTOZERO_BUFFER_FIXED_HPP
#define PROTOZERO_BUFFER_FIXED_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.
*****************************************************************************/
/**
* @file buffer_fixed.hpp
*
* @brief Contains the fixed_size_buffer_adaptor class.
*/
#include "buffer_tmpl.hpp"
#include "config.hpp"
#include <algorithm>
#include <cstddef>
#include <iterator>
#include <stdexcept>
namespace protozero {
/**
* This class can be used instead of std::string if you want to create a
* vector tile in a fixed-size buffer. Any operation that needs more space
* than is available will fail with a std::length_error exception.
*/
class fixed_size_buffer_adaptor {
char* m_data;
std::size_t m_capacity;
std::size_t m_size = 0;
public:
/// @cond usual container typedefs not documented
using size_type = std::size_t;
using value_type = char;
using reference = value_type&;
using const_reference = const value_type&;
using pointer = value_type*;
using const_pointer = const value_type*;
using iterator = pointer;
using const_iterator = const_pointer;
/// @endcond
/**
* Constructor.
*
* @param data Pointer to some memory allocated for the buffer.
* @param capacity Number of bytes available.
*/
fixed_size_buffer_adaptor(char* data, std::size_t capacity) noexcept :
m_data(data),
m_capacity(capacity) {
}
/**
* Constructor.
*
* @param container Some container class supporting the member functions
* data() and size().
*/
template <typename T>
explicit fixed_size_buffer_adaptor(T& container) :
m_data(container.data()),
m_capacity(container.size()) {
}
/// Returns a pointer to the data in the buffer.
const char* data() const noexcept {
return m_data;
}
/// Returns a pointer to the data in the buffer.
char* data() noexcept {
return m_data;
}
/// The capacity this buffer was created with.
std::size_t capacity() const noexcept {
return m_capacity;
}
/// The number of bytes used in the buffer. Always <= capacity().
std::size_t size() const noexcept {
return m_size;
}
/// Return iterator to beginning of data.
char* begin() noexcept {
return m_data;
}
/// Return iterator to beginning of data.
const char* begin() const noexcept {
return m_data;
}
/// Return iterator to beginning of data.
const char* cbegin() const noexcept {
return m_data;
}
/// Return iterator to end of data.
char* end() noexcept {
return m_data + m_size;
}
/// Return iterator to end of data.
const char* end() const noexcept {
return m_data + m_size;
}
/// Return iterator to end of data.
const char* cend() const noexcept {
return m_data + m_size;
}
/// @cond INTERNAL
// Do not rely on anything beyond this point
void append(const char* data, std::size_t count) {
if (m_size + count > m_capacity) {
throw std::length_error{"fixed size data store exhausted"};
}
std::copy_n(data, count, m_data + m_size);
m_size += count;
}
void append_zeros(std::size_t count) {
if (m_size + count > m_capacity) {
throw std::length_error{"fixed size data store exhausted"};
}
std::fill_n(m_data + m_size, count, '\0');
m_size += count;
}
void resize(std::size_t size) {
protozero_assert(size < m_size);
if (size > m_capacity) {
throw std::length_error{"fixed size data store exhausted"};
}
m_size = size;
}
void erase_range(std::size_t from, std::size_t to) {
protozero_assert(from <= m_size);
protozero_assert(to <= m_size);
protozero_assert(from < to);
std::copy(m_data + to, m_data + m_size, m_data + from);
m_size -= (to - from);
}
char* at_pos(std::size_t pos) {
protozero_assert(pos <= m_size);
return m_data + pos;
}
void push_back(char ch) {
if (m_size >= m_capacity) {
throw std::length_error{"fixed size data store exhausted"};
}
m_data[m_size++] = ch;
}
/// @endcond
}; // class fixed_size_buffer_adaptor
/// @cond INTERNAL
template <>
struct buffer_customization<fixed_size_buffer_adaptor> {
static std::size_t size(const fixed_size_buffer_adaptor* buffer) noexcept {
return buffer->size();
}
static void append(fixed_size_buffer_adaptor* buffer, const char* data, std::size_t count) {
buffer->append(data, count);
}
static void append_zeros(fixed_size_buffer_adaptor* buffer, std::size_t count) {
buffer->append_zeros(count);
}
static void resize(fixed_size_buffer_adaptor* buffer, std::size_t size) {
buffer->resize(size);
}
static void reserve_additional(fixed_size_buffer_adaptor* /*buffer*/, std::size_t /*size*/) {
/* nothing to be done for fixed-size buffers */
}
static void erase_range(fixed_size_buffer_adaptor* buffer, std::size_t from, std::size_t to) {
buffer->erase_range(from, to);
}
static char* at_pos(fixed_size_buffer_adaptor* buffer, std::size_t pos) {
return buffer->at_pos(pos);
}
static void push_back(fixed_size_buffer_adaptor* buffer, char ch) {
buffer->push_back(ch);
}
};
/// @endcond
} // namespace protozero
#endif // PROTOZERO_BUFFER_FIXED_HPP

View File

@ -0,0 +1,76 @@
#ifndef PROTOZERO_BUFFER_STRING_HPP
#define PROTOZERO_BUFFER_STRING_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.
*****************************************************************************/
/**
* @file buffer_string.hpp
*
* @brief Contains the customization points for buffer implementation based
* on std::string
*/
#include "buffer_tmpl.hpp"
#include <cstddef>
#include <iterator>
#include <string>
namespace protozero {
// Implementation of buffer customizations points for std::string
/// @cond INTERNAL
template <>
struct buffer_customization<std::string> {
static std::size_t size(const std::string* buffer) noexcept {
return buffer->size();
}
static void append(std::string* buffer, const char* data, std::size_t count) {
buffer->append(data, count);
}
static void append_zeros(std::string* buffer, std::size_t count) {
buffer->append(count, '\0');
}
static void resize(std::string* buffer, std::size_t size) {
protozero_assert(size < buffer->size());
buffer->resize(size);
}
static void reserve_additional(std::string* buffer, std::size_t size) {
buffer->reserve(buffer->size() + size);
}
static void erase_range(std::string* buffer, std::size_t from, std::size_t to) {
protozero_assert(from <= buffer->size());
protozero_assert(to <= buffer->size());
protozero_assert(from <= to);
buffer->erase(std::next(buffer->begin(), from), std::next(buffer->begin(), to));
}
static char* at_pos(std::string* buffer, std::size_t pos) {
protozero_assert(pos <= buffer->size());
return (&*buffer->begin()) + pos;
}
static void push_back(std::string* buffer, char ch) {
buffer->push_back(ch);
}
};
/// @endcond
} // namespace protozero
#endif // PROTOZERO_BUFFER_STRING_HPP

View File

@ -0,0 +1,113 @@
#ifndef PROTOZERO_BUFFER_TMPL_HPP
#define PROTOZERO_BUFFER_TMPL_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.
*****************************************************************************/
/**
* @file buffer_tmpl.hpp
*
* @brief Contains the customization points for buffer implementations.
*/
#include <cstddef>
#include <iterator>
#include <string>
namespace protozero {
// Implementation of buffer customizations points for std::string
/// @cond INTERNAL
template <typename T>
struct buffer_customization {
/**
* Get the number of bytes currently used in the buffer.
*
* @param buffer Pointer to the buffer.
* @returns number of bytes used in the buffer.
*/
static std::size_t size(const std::string* buffer);
/**
* Append count bytes from data to the buffer.
*
* @param buffer Pointer to the buffer.
* @param data Pointer to the data.
* @param count Number of bytes to be added to the buffer.
*/
static void append(std::string* buffer, const char* data, std::size_t count);
/**
* Append count zero bytes to the buffer.
*
* @param buffer Pointer to the buffer.
* @param count Number of bytes to be added to the buffer.
*/
static void append_zeros(std::string* buffer, std::size_t count);
/**
* Shrink the buffer to the specified size. The new size will always be
* smaller than the current size.
*
* @param buffer Pointer to the buffer.
* @param size New size of the buffer.
*
* @pre size < current size of buffer
*/
static void resize(std::string* buffer, std::size_t size);
/**
* Reserve an additional size bytes for use in the buffer. This is used for
* variable-sized buffers to tell the buffer implementation that soon more
* memory will be used. The implementation can ignore this.
*
* @param buffer Pointer to the buffer.
* @param size Number of bytes to reserve.
*/
static void reserve_additional(std::string* buffer, std::size_t size);
/**
* Delete data from the buffer. This must move back the data after the
* part being deleted and resize the buffer accordingly.
*
* @param buffer Pointer to the buffer.
* @param from Offset into the buffer where we want to erase from.
* @param to Offset into the buffer one past the last byte we want to erase.
*
* @pre from, to <= size of the buffer, from < to
*/
static void erase_range(std::string* buffer, std::size_t from, std::size_t to);
/**
* Return a pointer to the memory at the specified position in the buffer.
*
* @param buffer Pointer to the buffer.
* @param pos The position in the buffer.
* @returns pointer to the memory in the buffer at the specified position.
*
* @pre pos <= size of the buffer
*/
static char* at_pos(std::string* buffer, std::size_t pos);
/**
* Add a char to the buffer incrementing the number of chars in the buffer.
*
* @param buffer Pointer to the buffer.
* @param ch The character to add.
*/
static void push_back(std::string* buffer, char ch);
};
/// @endcond
} // namespace protozero
#endif // PROTOZERO_BUFFER_TMPL_HPP

View File

@ -0,0 +1,76 @@
#ifndef PROTOZERO_BUFFER_VECTOR_HPP
#define PROTOZERO_BUFFER_VECTOR_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.
*****************************************************************************/
/**
* @file buffer_vector.hpp
*
* @brief Contains the customization points for buffer implementation based
* on std::vector<char>
*/
#include "buffer_tmpl.hpp"
#include <cstddef>
#include <iterator>
#include <vector>
namespace protozero {
// Implementation of buffer customizations points for std::vector<char>
/// @cond INTERNAL
template <>
struct buffer_customization<std::vector<char>> {
static std::size_t size(const std::vector<char>* buffer) noexcept {
return buffer->size();
}
static void append(std::vector<char>* buffer, const char* data, std::size_t count) {
buffer->insert(buffer->end(), data, data + count);
}
static void append_zeros(std::vector<char>* buffer, std::size_t count) {
buffer->insert(buffer->end(), count, '\0');
}
static void resize(std::vector<char>* buffer, std::size_t size) {
protozero_assert(size < buffer->size());
buffer->resize(size);
}
static void reserve_additional(std::vector<char>* buffer, std::size_t size) {
buffer->reserve(buffer->size() + size);
}
static void erase_range(std::vector<char>* buffer, std::size_t from, std::size_t to) {
protozero_assert(from <= buffer->size());
protozero_assert(to <= buffer->size());
protozero_assert(from <= to);
buffer->erase(std::next(buffer->begin(), from), std::next(buffer->begin(), to));
}
static char* at_pos(std::vector<char>* buffer, std::size_t pos) {
protozero_assert(pos <= buffer->size());
return (&*buffer->begin()) + pos;
}
static void push_back(std::vector<char>* buffer, char ch) {
buffer->push_back(ch);
}
};
/// @endcond
} // namespace protozero
#endif // PROTOZERO_BUFFER_VECTOR_HPP

View File

@ -16,7 +16,7 @@ documentation.
* @brief Contains functions to swap bytes in values (for different endianness).
*/
#include <protozero/config.hpp>
#include "config.hpp"
#include <cstdint>
@ -27,10 +27,10 @@ inline uint32_t byteswap_impl(uint32_t value) noexcept {
#ifdef PROTOZERO_USE_BUILTIN_BSWAP
return __builtin_bswap32(value);
#else
return ((value & 0xff000000) >> 24) |
((value & 0x00ff0000) >> 8) |
((value & 0x0000ff00) << 8) |
((value & 0x000000ff) << 24);
return ((value & 0xff000000U) >> 24U) |
((value & 0x00ff0000U) >> 8U) |
((value & 0x0000ff00U) << 8U) |
((value & 0x000000ffU) << 24U);
#endif
}
@ -38,46 +38,62 @@ inline uint64_t byteswap_impl(uint64_t value) noexcept {
#ifdef PROTOZERO_USE_BUILTIN_BSWAP
return __builtin_bswap64(value);
#else
return ((value & 0xff00000000000000ULL) >> 56) |
((value & 0x00ff000000000000ULL) >> 40) |
((value & 0x0000ff0000000000ULL) >> 24) |
((value & 0x000000ff00000000ULL) >> 8) |
((value & 0x00000000ff000000ULL) << 8) |
((value & 0x0000000000ff0000ULL) << 24) |
((value & 0x000000000000ff00ULL) << 40) |
((value & 0x00000000000000ffULL) << 56);
return ((value & 0xff00000000000000ULL) >> 56U) |
((value & 0x00ff000000000000ULL) >> 40U) |
((value & 0x0000ff0000000000ULL) >> 24U) |
((value & 0x000000ff00000000ULL) >> 8U) |
((value & 0x00000000ff000000ULL) << 8U) |
((value & 0x0000000000ff0000ULL) << 24U) |
((value & 0x000000000000ff00ULL) << 40U) |
((value & 0x00000000000000ffULL) << 56U);
#endif
}
} // end namespace detail
/// byteswap the data pointed to by ptr in-place.
inline void byteswap_inplace(uint32_t* ptr) noexcept {
*ptr = byteswap_impl(*ptr);
*ptr = detail::byteswap_impl(*ptr);
}
/// byteswap the data pointed to by ptr in-place.
inline void byteswap_inplace(uint64_t* ptr) noexcept {
*ptr = byteswap_impl(*ptr);
*ptr = detail::byteswap_impl(*ptr);
}
/// byteswap the data pointed to by ptr in-place.
inline void byteswap_inplace(int32_t* ptr) noexcept {
auto bptr = reinterpret_cast<uint32_t*>(ptr);
*bptr = byteswap_impl(*bptr);
auto* bptr = reinterpret_cast<uint32_t*>(ptr);
*bptr = detail::byteswap_impl(*bptr);
}
/// byteswap the data pointed to by ptr in-place.
inline void byteswap_inplace(int64_t* ptr) noexcept {
auto bptr = reinterpret_cast<uint64_t*>(ptr);
*bptr = byteswap_impl(*bptr);
auto* bptr = reinterpret_cast<uint64_t*>(ptr);
*bptr = detail::byteswap_impl(*bptr);
}
/// byteswap the data pointed to by ptr in-place.
inline void byteswap_inplace(float* ptr) noexcept {
auto bptr = reinterpret_cast<uint32_t*>(ptr);
*bptr = byteswap_impl(*bptr);
auto* bptr = reinterpret_cast<uint32_t*>(ptr);
*bptr = detail::byteswap_impl(*bptr);
}
/// byteswap the data pointed to by ptr in-place.
inline void byteswap_inplace(double* ptr) noexcept {
auto bptr = reinterpret_cast<uint64_t*>(ptr);
*bptr = byteswap_impl(*bptr);
auto* bptr = reinterpret_cast<uint64_t*>(ptr);
*bptr = detail::byteswap_impl(*bptr);
}
namespace detail {
// Added for backwards compatibility with any code that might use this
// function (even if it shouldn't have). Will be removed in a later
// version of protozero.
using ::protozero::byteswap_inplace;
} // end namespace detail
} // end namespace protozero
#endif // PROTOZERO_BYTESWAP_HPP

View File

@ -16,7 +16,7 @@ documentation.
* @brief Contains the implementation of the data_view class.
*/
#include <protozero/config.hpp>
#include "config.hpp"
#include <algorithm>
#include <cstddef>
@ -55,8 +55,8 @@ public:
* @param length Length of the data.
*/
constexpr data_view(const char* ptr, std::size_t length) noexcept
: m_data(ptr),
m_size(length) {
: m_data{ptr},
m_size{length} {
}
/**
@ -65,8 +65,8 @@ public:
* @param str String with the data.
*/
data_view(const std::string& str) noexcept // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
: m_data(str.data()),
m_size(str.size()) {
: m_data{str.data()},
m_size{str.size()} {
}
/**
@ -75,8 +75,8 @@ public:
* @param ptr Pointer to the data.
*/
data_view(const char* ptr) noexcept // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
: m_data(ptr),
m_size(std::strlen(ptr)) {
: m_data{ptr},
m_size{std::strlen(ptr)} {
}
/**
@ -141,8 +141,8 @@ public:
*
* @pre Must not be default constructed data_view.
*/
int compare(data_view other) const {
protozero_assert(m_data && other.m_data);
int compare(data_view other) const noexcept {
assert(m_data && other.m_data);
const int cmp = std::memcmp(data(), other.data(),
std::min(size(), other.size()));
if (cmp == 0) {

View File

@ -16,8 +16,8 @@ documentation.
* @brief Contains the iterators for access to packed repeated fields.
*/
#include <protozero/config.hpp>
#include <protozero/varint.hpp>
#include "config.hpp"
#include "varint.hpp"
#if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
# include <protozero/byteswap.hpp>
@ -56,7 +56,7 @@ public:
* Default constructor. Create empty iterator_range.
*/
constexpr iterator_range() :
P(iterator{}, iterator{}) {
P{iterator{}, iterator{}} {
}
/**
@ -66,8 +66,8 @@ public:
* @param last_iterator Iterator to end of range.
*/
constexpr iterator_range(iterator&& first_iterator, iterator&& last_iterator) :
P(std::forward<iterator>(first_iterator),
std::forward<iterator>(last_iterator)) {
P{std::forward<iterator>(first_iterator),
std::forward<iterator>(last_iterator)} {
}
/// Return iterator to beginning of range.
@ -164,6 +164,8 @@ class const_fixed_iterator {
public:
/// @cond usual iterator functions not documented
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
@ -173,7 +175,7 @@ public:
const_fixed_iterator() noexcept = default;
explicit const_fixed_iterator(const char* data) noexcept :
m_data(data) {
m_data{data} {
}
const_fixed_iterator(const const_fixed_iterator&) noexcept = default;
@ -184,11 +186,11 @@ public:
~const_fixed_iterator() noexcept = default;
value_type operator*() const {
value_type operator*() const noexcept {
value_type result;
std::memcpy(&result, m_data, sizeof(value_type));
#if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
detail::byteswap_inplace(&result);
byteswap_inplace(&result);
#endif
return result;
}
@ -204,14 +206,6 @@ public:
return tmp;
}
bool operator==(const_fixed_iterator rhs) const noexcept {
return m_data == rhs.m_data;
}
bool operator!=(const_fixed_iterator rhs) const noexcept {
return !(*this == rhs);
}
const_fixed_iterator& operator--() noexcept {
m_data -= sizeof(value_type);
return *this;
@ -223,6 +217,14 @@ public:
return tmp;
}
friend bool operator==(const_fixed_iterator lhs, const_fixed_iterator rhs) noexcept {
return lhs.m_data == rhs.m_data;
}
friend bool operator!=(const_fixed_iterator lhs, const_fixed_iterator rhs) noexcept {
return !(lhs == rhs);
}
friend bool operator<(const_fixed_iterator lhs, const_fixed_iterator rhs) noexcept {
return lhs.m_data < rhs.m_data;
}
@ -237,7 +239,6 @@ public:
friend bool operator>=(const_fixed_iterator lhs, const_fixed_iterator rhs) noexcept {
return !(lhs < rhs);
}
const_fixed_iterator& operator+=(difference_type val) noexcept {
@ -276,6 +277,8 @@ public:
return *(*this + n);
}
/// @endcond
}; // class const_fixed_iterator
/**
@ -288,13 +291,15 @@ class const_varint_iterator {
protected:
/// Pointer to current iterator position
const char* m_data = nullptr;
const char* m_data = nullptr; // NOLINT(misc-non-private-member-variables-in-classes, cppcoreguidelines-non-private-member-variables-in-classes,-warnings-as-errors)
/// Pointer to end iterator position
const char* m_end = nullptr;
const char* m_end = nullptr; // NOLINT(misc-non-private-member-variables-in-classes, cppcoreguidelines-non-private-member-variables-in-classes,-warnings-as-errors)
public:
/// @cond usual iterator functions not documented
using iterator_category = std::forward_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
@ -302,19 +307,24 @@ public:
using reference = value_type&;
static difference_type distance(const_varint_iterator begin, const_varint_iterator end) noexcept {
// The "distance" between default initialized const_varint_iterator's
// is always 0.
if (!begin.m_data) {
return 0;
}
// We know that each varint contains exactly one byte with the most
// significant bit not set. We can use this to quickly figure out
// how many varints there are without actually decoding the varints.
return std::count_if(begin.m_data, end.m_data, [](char c) noexcept {
return (static_cast<unsigned char>(c) & 0x80u) == 0;
return (static_cast<unsigned char>(c) & 0x80U) == 0;
});
}
const_varint_iterator() noexcept = default;
const_varint_iterator(const char* data, const char* end) noexcept :
m_data(data),
m_end(end) {
m_data{data},
m_end{end} {
}
const_varint_iterator(const const_varint_iterator&) noexcept = default;
@ -326,16 +336,19 @@ public:
~const_varint_iterator() noexcept = default;
value_type operator*() const {
protozero_assert(m_data);
const char* d = m_data; // will be thrown away
return static_cast<value_type>(decode_varint(&d, m_end));
}
const_varint_iterator& operator++() {
protozero_assert(m_data);
skip_varint(&m_data, m_end);
return *this;
}
const_varint_iterator operator++(int) {
protozero_assert(m_data);
const const_varint_iterator tmp{*this};
++(*this);
return tmp;
@ -349,6 +362,8 @@ public:
return !(*this == rhs);
}
/// @endcond
}; // class const_varint_iterator
/**
@ -360,6 +375,8 @@ class const_svarint_iterator : public const_varint_iterator<T> {
public:
/// @cond usual iterator functions not documented
using iterator_category = std::forward_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
@ -367,11 +384,11 @@ public:
using reference = value_type&;
const_svarint_iterator() noexcept :
const_varint_iterator<T>() {
const_varint_iterator<T>{} {
}
const_svarint_iterator(const char* data, const char* end) noexcept :
const_varint_iterator<T>(data, end) {
const_varint_iterator<T>{data, end} {
}
const_svarint_iterator(const const_svarint_iterator&) = default;
@ -383,21 +400,26 @@ public:
~const_svarint_iterator() = default;
value_type operator*() const {
protozero_assert(this->m_data);
const char* d = this->m_data; // will be thrown away
return static_cast<value_type>(decode_zigzag64(decode_varint(&d, this->m_end)));
}
const_svarint_iterator& operator++() {
protozero_assert(this->m_data);
skip_varint(&this->m_data, this->m_end);
return *this;
}
const_svarint_iterator operator++(int) {
protozero_assert(this->m_data);
const const_svarint_iterator tmp{*this};
++(*this);
return tmp;
}
/// @endcond
}; // class const_svarint_iterator
} // end namespace protozero
@ -408,6 +430,8 @@ namespace std {
// functions can't be partially specialized, we have to do this for
// every value_type we are using.
/// @cond individual overloads do not need to be documented
template <>
inline typename protozero::const_varint_iterator<int32_t>::difference_type
distance<protozero::const_varint_iterator<int32_t>>(protozero::const_varint_iterator<int32_t> first, // NOLINT(readability-inconsistent-declaration-parameter-name)
@ -450,6 +474,8 @@ namespace std {
return protozero::const_svarint_iterator<int64_t>::distance(first, last);
}
/// @endcond
} // end namespace std
#endif // PROTOZERO_ITERATORS_HPP

View File

@ -16,249 +16,16 @@ documentation.
* @brief Contains the pbf_builder template class.
*/
#include <protozero/pbf_writer.hpp>
#include <protozero/types.hpp>
#include "basic_pbf_builder.hpp"
#include "pbf_writer.hpp"
#include <type_traits>
#include <string>
namespace protozero {
/**
* The pbf_builder is used to write PBF formatted messages into a buffer. It
* is based on the pbf_writer class and has all the same methods. The
* difference is that while the pbf_writer class takes an integer tag,
* this template class takes a tag of the template type T. The idea is that
* T will be an enumeration value and this helps reduce the possibility of
* programming errors.
*
* Almost all methods in this class can throw an std::bad_alloc exception if
* the std::string used as a buffer wants to resize.
*
* Read the tutorial to understand how this class is used.
*/
/// Specialization of basic_pbf_builder using std::string as buffer type.
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:
/// The type of messages this class will build.
using enum_type = T;
pbf_builder() = default;
/**
* Create a builder using the given string as a data store. The object
* stores a reference to that string and adds all data to it. The string
* doesn't have to be empty. The pbf_message object will just append data.
*/
explicit pbf_builder(std::string& data) noexcept :
pbf_writer(data) {
}
/**
* Construct a pbf_builder for a submessage from the pbf_message or
* pbf_writer of the parent message.
*
* @param parent_writer The parent pbf_message or pbf_writer
* @param tag Tag of the field that will be written
*/
template <typename P>
pbf_builder(pbf_writer& parent_writer, P tag) noexcept :
pbf_writer(parent_writer, pbf_tag_type(tag)) {
}
/// @cond INTERNAL
#define PROTOZERO_WRITER_WRAP_ADD_SCALAR(name, type) \
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)
#undef PROTOZERO_WRITER_WRAP_ADD_SCALAR
/// @endcond
/**
* Add "bytes" field to data.
*
* @param tag Tag of the field
* @param value Pointer to value to be written
* @param size Number of bytes to be written
*/
void add_bytes(T tag, const char* value, std::size_t size) {
pbf_writer::add_bytes(pbf_tag_type(tag), value, size);
}
/**
* Add "bytes" field to data.
*
* @param tag Tag of the field
* @param value Value to be written
*/
void add_bytes(T tag, const data_view& value) {
pbf_writer::add_bytes(pbf_tag_type(tag), value);
}
/**
* Add "bytes" field to data.
*
* @param tag Tag of the field
* @param value Value to be written
*/
void add_bytes(T tag, const std::string& value) {
pbf_writer::add_bytes(pbf_tag_type(tag), value);
}
/**
* Add "bytes" field to data. Bytes from the value are written until
* a null byte is encountered. The null byte is not added.
*
* @param tag Tag of the field
* @param value Pointer to zero-delimited value to be written
*/
void add_bytes(T tag, const char* value) {
pbf_writer::add_bytes(pbf_tag_type(tag), value);
}
/**
* Add "bytes" field to data using vectored input. All the data in the
* 2nd and further arguments is "concatenated" with only a single copy
* into the final buffer.
*
* This will work with objects of any type supporting the data() and
* size() methods like std::string or protozero::data_view.
*
* Example:
* @code
* std::string data1 = "abc";
* std::string data2 = "xyz";
* builder.add_bytes_vectored(1, data1, data2);
* @endcode
*
* @tparam Ts List of types supporting data() and size() methods.
* @param tag Tag of the field
* @param values List of objects of types Ts with data to be appended.
*/
template <typename... Ts>
void add_bytes_vectored(T tag, Ts&&... values) {
pbf_writer::add_bytes_vectored(pbf_tag_type(tag), std::forward<Ts>(values)...);
}
/**
* Add "string" field to data.
*
* @param tag Tag of the field
* @param value Pointer to value to be written
* @param size Number of bytes to be written
*/
void add_string(T tag, const char* value, std::size_t size) {
pbf_writer::add_string(pbf_tag_type(tag), value, size);
}
/**
* Add "string" field to data.
*
* @param tag Tag of the field
* @param value Value to be written
*/
void add_string(T tag, const data_view& value) {
pbf_writer::add_string(pbf_tag_type(tag), value);
}
/**
* Add "string" field to data.
*
* @param tag Tag of the field
* @param value Value to be written
*/
void add_string(T tag, const std::string& value) {
pbf_writer::add_string(pbf_tag_type(tag), value);
}
/**
* Add "string" field to data. Bytes from the value are written until
* a null byte is encountered. The null byte is not added.
*
* @param tag Tag of the field
* @param value Pointer to value to be written
*/
void add_string(T tag, const char* value) {
pbf_writer::add_string(pbf_tag_type(tag), value);
}
/**
* Add "message" field to data.
*
* @param tag Tag of the field
* @param value Pointer to message to be written
* @param size Length of the message
*/
void add_message(T tag, const char* value, std::size_t size) {
pbf_writer::add_message(pbf_tag_type(tag), value, size);
}
/**
* Add "message" field to data.
*
* @param tag Tag of the field
* @param value Value to be written. The value must be a complete message.
*/
void add_message(T tag, const data_view& value) {
pbf_writer::add_message(pbf_tag_type(tag), value);
}
/**
* Add "message" field to data.
*
* @param tag Tag of the field
* @param value Value to be written. The value must be a complete message.
*/
void add_message(T tag, const std::string& value) {
pbf_writer::add_message(pbf_tag_type(tag), value);
}
/// @cond INTERNAL
#define PROTOZERO_WRITER_WRAP_ADD_PACKED(name) \
template <typename InputIterator> \
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)
#undef PROTOZERO_WRITER_WRAP_ADD_PACKED
/// @endcond
}; // class pbf_builder
using pbf_builder = basic_pbf_builder<std::string, T>;
} // end namespace protozero

View File

@ -16,8 +16,8 @@ documentation.
* @brief Contains the pbf_message template class.
*/
#include <protozero/pbf_reader.hpp>
#include <protozero/types.hpp>
#include "pbf_reader.hpp"
#include "types.hpp"
#include <type_traits>
@ -78,7 +78,7 @@ public:
*/
template <typename... Args>
pbf_message(Args&&... args) noexcept : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
pbf_reader(std::forward<Args>(args)...) {
pbf_reader{std::forward<Args>(args)...} {
}
/**

View File

@ -16,12 +16,12 @@ documentation.
* @brief Contains the pbf_reader class.
*/
#include <protozero/config.hpp>
#include <protozero/data_view.hpp>
#include <protozero/exception.hpp>
#include <protozero/iterators.hpp>
#include <protozero/types.hpp>
#include <protozero/varint.hpp>
#include "config.hpp"
#include "data_view.hpp"
#include "exception.hpp"
#include "iterators.hpp"
#include "types.hpp"
#include "varint.hpp"
#if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
# include <protozero/byteswap.hpp>
@ -80,7 +80,7 @@ class pbf_reader {
skip_bytes(sizeof(T));
std::memcpy(&result, data, sizeof(T));
#if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN
detail::byteswap_inplace(&result);
byteswap_inplace(&result);
#endif
return result;
}
@ -98,7 +98,8 @@ class pbf_reader {
template <typename T>
T get_varint() {
return static_cast<T>(decode_varint(&m_data, m_end));
const auto val = static_cast<T>(decode_varint(&m_data, m_end));
return val;
}
template <typename T>
@ -112,7 +113,7 @@ class pbf_reader {
}
void skip_bytes(pbf_length_type len) {
if (m_data + len > m_end) {
if (m_end - m_data < static_cast<ptrdiff_t>(len)) {
throw end_of_buffer_exception{};
}
m_data += len;
@ -151,8 +152,8 @@ public:
* @post There is no current field.
*/
explicit pbf_reader(const data_view& view) noexcept
: m_data(view.data()),
m_end(view.data() + view.size()) {
: m_data{view.data()},
m_end{view.data() + view.size()} {
}
/**
@ -166,8 +167,8 @@ public:
* @post There is no current field.
*/
pbf_reader(const char* data, std::size_t size) noexcept
: m_data(data),
m_end(data + size) {
: m_data{data},
m_end{data + size} {
}
#ifndef PROTOZERO_STRICT_API
@ -183,8 +184,8 @@ public:
* @deprecated Use one of the other constructors.
*/
explicit pbf_reader(const std::pair<const char*, std::size_t>& data) noexcept
: m_data(data.first),
m_end(data.first + data.second) {
: m_data{data.first},
m_end{data.first + data.second} {
}
#endif
@ -199,8 +200,8 @@ public:
* @post There is no current field.
*/
explicit pbf_reader(const std::string& data) noexcept
: m_data(data.data()),
m_end(data.data() + data.size()) {
: m_data{data.data()},
m_end{data.data() + data.size()} {
}
/**
@ -242,7 +243,14 @@ public:
* read.
*/
operator bool() const noexcept { // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
return m_data < m_end;
return m_data != m_end;
}
/**
* Get a view of the not yet read data.
*/
data_view data() const noexcept {
return {m_data, static_cast<std::size_t>(m_end - m_data)};
}
/**
@ -279,7 +287,7 @@ public:
}
const auto value = get_varint<uint32_t>();
m_tag = pbf_tag_type(value >> 3u);
m_tag = pbf_tag_type(value >> 3U);
// tags 0 and 19000 to 19999 are not allowed as per
// https://developers.google.com/protocol-buffers/docs/proto#assigning-tags
@ -287,7 +295,7 @@ public:
throw invalid_tag_exception{};
}
m_wire_type = pbf_wire_type(value & 0x07u);
m_wire_type = pbf_wire_type(value & 0x07U);
switch (m_wire_type) {
case pbf_wire_type::varint:
case pbf_wire_type::fixed64:
@ -486,9 +494,9 @@ public:
bool get_bool() {
protozero_assert(tag() != 0 && "call next() before accessing field value");
protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
const auto data = m_data;
const bool result = m_data[0] != 0;
skip_varint(&m_data, m_end);
return data[0] != 0;
return result;
}
/**

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ documentation.
* @brief Contains the declaration of low-level types used in the pbf format.
*/
#include <protozero/config.hpp>
#include "config.hpp"
#include <algorithm>
#include <cstddef>
@ -53,7 +53,7 @@ enum class pbf_wire_type : uint32_t {
*/
template <typename T>
constexpr inline uint32_t tag_and_type(T tag, pbf_wire_type wire_type) noexcept {
return (static_cast<uint32_t>(static_cast<pbf_tag_type>(tag)) << 3u) | static_cast<uint32_t>(wire_type);
return (static_cast<uint32_t>(static_cast<pbf_tag_type>(tag)) << 3U) | static_cast<uint32_t>(wire_type);
}
/**

View File

@ -16,7 +16,8 @@ documentation.
* @brief Contains low-level varint and zigzag encoding and decoding functions.
*/
#include <protozero/exception.hpp>
#include "buffer_tmpl.hpp"
#include "exception.hpp"
#include <cstdint>
@ -31,30 +32,30 @@ namespace detail {
// from https://github.com/facebook/folly/blob/master/folly/Varint.h
inline uint64_t decode_varint_impl(const char** data, const char* end) {
const auto begin = reinterpret_cast<const int8_t*>(*data);
const auto iend = reinterpret_cast<const int8_t*>(end);
const auto* begin = reinterpret_cast<const int8_t*>(*data);
const auto* iend = reinterpret_cast<const int8_t*>(end);
const int8_t* p = begin;
uint64_t val = 0;
if (iend - begin >= max_varint_length) { // fast path
do {
int64_t b;
b = *p++; val = uint64_t((b & 0x7fu) ); if (b >= 0) { break; }
b = *p++; val |= uint64_t((b & 0x7fu) << 7u); if (b >= 0) { break; }
b = *p++; val |= uint64_t((b & 0x7fu) << 14u); if (b >= 0) { break; }
b = *p++; val |= uint64_t((b & 0x7fu) << 21u); if (b >= 0) { break; }
b = *p++; val |= uint64_t((b & 0x7fu) << 28u); if (b >= 0) { break; }
b = *p++; val |= uint64_t((b & 0x7fu) << 35u); if (b >= 0) { break; }
b = *p++; val |= uint64_t((b & 0x7fu) << 42u); if (b >= 0) { break; }
b = *p++; val |= uint64_t((b & 0x7fu) << 49u); if (b >= 0) { break; }
b = *p++; val |= uint64_t((b & 0x7fu) << 56u); if (b >= 0) { break; }
b = *p++; val |= uint64_t((b & 0x01u) << 63u); if (b >= 0) { break; }
int64_t b = *p++;
val = ((uint64_t(b) & 0x7fU) ); if (b >= 0) { break; }
b = *p++; val |= ((uint64_t(b) & 0x7fU) << 7U); if (b >= 0) { break; }
b = *p++; val |= ((uint64_t(b) & 0x7fU) << 14U); if (b >= 0) { break; }
b = *p++; val |= ((uint64_t(b) & 0x7fU) << 21U); if (b >= 0) { break; }
b = *p++; val |= ((uint64_t(b) & 0x7fU) << 28U); if (b >= 0) { break; }
b = *p++; val |= ((uint64_t(b) & 0x7fU) << 35U); if (b >= 0) { break; }
b = *p++; val |= ((uint64_t(b) & 0x7fU) << 42U); if (b >= 0) { break; }
b = *p++; val |= ((uint64_t(b) & 0x7fU) << 49U); if (b >= 0) { break; }
b = *p++; val |= ((uint64_t(b) & 0x7fU) << 56U); if (b >= 0) { break; }
b = *p++; val |= ((uint64_t(b) & 0x01U) << 63U); if (b >= 0) { break; }
throw varint_too_long_exception{};
} while (false);
} else {
unsigned int shift = 0;
while (p != iend && *p < 0) {
val |= uint64_t(*p++ & 0x7fu) << shift;
val |= (uint64_t(*p++) & 0x7fU) << shift;
shift += 7;
}
if (p == iend) {
@ -88,7 +89,7 @@ namespace detail {
*/
inline uint64_t decode_varint(const char** data, const char* end) {
// If this is a one-byte varint, decode it here.
if (end != *data && ((**data & 0x80u) == 0)) {
if (end != *data && ((static_cast<uint64_t>(**data) & 0x80U) == 0)) {
const auto val = static_cast<uint64_t>(**data);
++(*data);
return val;
@ -110,15 +111,15 @@ inline uint64_t decode_varint(const char** data, const char* end) {
* before the end of the varint.
*/
inline void skip_varint(const char** data, const char* end) {
const auto begin = reinterpret_cast<const int8_t*>(*data);
const auto iend = reinterpret_cast<const int8_t*>(end);
const auto* begin = reinterpret_cast<const int8_t*>(*data);
const auto* iend = reinterpret_cast<const int8_t*>(end);
const int8_t* p = begin;
while (p != iend && *p < 0) {
++p;
}
if (p >= begin + max_varint_length) {
if (p - begin >= max_varint_length) {
throw varint_too_long_exception{};
}
@ -140,17 +141,73 @@ inline void skip_varint(const char** data, const char* end) {
* @param value The integer that will be encoded.
* @returns the number of bytes written
* @throws Any exception thrown by increment or dereference operator on data.
* @deprecated Use add_varint_to_buffer() instead.
*/
template <typename T>
inline int write_varint(T data, uint64_t value) {
int n = 1;
while (value >= 0x80u) {
*data++ = char((value & 0x7fu) | 0x80u);
value >>= 7u;
while (value >= 0x80U) {
*data++ = char((value & 0x7fU) | 0x80U);
value >>= 7U;
++n;
}
*data = char(value);
return n;
}
/**
* Varint encode a 64 bit integer.
*
* @tparam TBuffer A buffer type.
* @param buffer Output buffer the varint will be written to.
* @param value The integer that will be encoded.
* @returns the number of bytes written
* @throws Any exception thrown by calling the buffer_push_back() function.
*/
template <typename TBuffer>
inline void add_varint_to_buffer(TBuffer* buffer, uint64_t value) {
while (value >= 0x80U) {
buffer_customization<TBuffer>::push_back(buffer, char((value & 0x7fU) | 0x80U));
value >>= 7U;
}
buffer_customization<TBuffer>::push_back(buffer, char(value));
}
/**
* Varint encode a 64 bit integer.
*
* @param data Where to add the varint. There must be enough space available!
* @param value The integer that will be encoded.
* @returns the number of bytes written
*/
inline int add_varint_to_buffer(char* data, uint64_t value) noexcept {
int n = 1;
while (value >= 0x80U) {
*data++ = char((value & 0x7fU) | 0x80U);
value >>= 7U;
++n;
}
*data = char(value);
return n;
}
/**
* Get the length of the varint the specified value would produce.
*
* @param value The integer to be encoded.
* @returns the number of bytes the varint would have if we created it.
*/
inline int length_of_varint(uint64_t value) noexcept {
int n = 1;
while (value >= 0x80U) {
value >>= 7U;
++n;
}
*data++ = char(value);
return n;
}
@ -159,28 +216,28 @@ inline int write_varint(T data, uint64_t value) {
* ZigZag encodes a 32 bit integer.
*/
inline constexpr uint32_t encode_zigzag32(int32_t value) noexcept {
return (static_cast<uint32_t>(value) << 1u) ^ (static_cast<uint32_t>(value >> 31u));
return (static_cast<uint32_t>(value) << 1U) ^ static_cast<uint32_t>(-static_cast<int32_t>(static_cast<uint32_t>(value) >> 31U));
}
/**
* ZigZag encodes a 64 bit integer.
*/
inline constexpr uint64_t encode_zigzag64(int64_t value) noexcept {
return (static_cast<uint64_t>(value) << 1u) ^ (static_cast<uint64_t>(value >> 63u));
return (static_cast<uint64_t>(value) << 1U) ^ static_cast<uint64_t>(-static_cast<int64_t>(static_cast<uint64_t>(value) >> 63U));
}
/**
* Decodes a 32 bit ZigZag-encoded integer.
*/
inline constexpr int32_t decode_zigzag32(uint32_t value) noexcept {
return static_cast<int32_t>(value >> 1u) ^ -static_cast<int32_t>(value & 1u);
return static_cast<int32_t>((value >> 1U) ^ static_cast<uint32_t>(-static_cast<int32_t>(value & 1U)));
}
/**
* Decodes a 64 bit ZigZag-encoded integer.
*/
inline constexpr int64_t decode_zigzag64(uint64_t value) noexcept {
return static_cast<int64_t>(value >> 1u) ^ -static_cast<int64_t>(value & 1u);
return static_cast<int64_t>((value >> 1U) ^ static_cast<uint64_t>(-static_cast<int64_t>(value & 1U)));
}
} // end namespace protozero

View File

@ -20,15 +20,15 @@ documentation.
#define PROTOZERO_VERSION_MAJOR 1
/// The minor version number
#define PROTOZERO_VERSION_MINOR 6
#define PROTOZERO_VERSION_MINOR 7
/// The patch number
#define PROTOZERO_VERSION_PATCH 2
#define PROTOZERO_VERSION_PATCH 0
/// 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.6.2"
#define PROTOZERO_VERSION_STRING "1.7.0"
#endif // PROTOZERO_VERSION_HPP

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,16 @@
# If called without a test case it will iterate over all test cases generating
# all data.
#
# This program should be called with the "test" directory as current directory.
#
set -e
if [ -z "$CXX" ]; then
echo "Please set CXX before running this script"
exit 1
fi
if [ -z "$1" ]; then
for dir in t/*; do
$0 $dir

View File

@ -0,0 +1,162 @@
#ifndef BUFFER_HPP
#define BUFFER_HPP
#include "test.hpp"
#include <protozero/buffer_fixed.hpp>
#include <protozero/buffer_string.hpp>
#include <protozero/buffer_vector.hpp>
// This "simulates" an externally defined buffer type to make sure our
// buffer adaptor functions do the right thing.
namespace test_external {
class ext_buffer : public std::string {
};
} // namespace test_external
namespace protozero {
template <>
struct buffer_customization<test_external::ext_buffer> {
static std::size_t size(const test_external::ext_buffer* buffer) noexcept {
return buffer->size();
}
static void append(test_external::ext_buffer* buffer, const char* data, std::size_t count) {
buffer->append(data, count);
}
static void append_zeros(test_external::ext_buffer* buffer, std::size_t count) {
buffer->append(count, '\0');
}
static void resize(test_external::ext_buffer* buffer, std::size_t size) {
protozero_assert(size < buffer->size());
buffer->resize(size);
}
static void reserve_additional(test_external::ext_buffer* buffer, std::size_t size) {
buffer->reserve(buffer->size() + size);
}
static void erase_range(test_external::ext_buffer* buffer, std::size_t from, std::size_t to) {
protozero_assert(from <= buffer->size());
protozero_assert(to <= buffer->size());
protozero_assert(from <= to);
buffer->erase(std::next(buffer->begin(), from), std::next(buffer->begin(), to));
}
static char* at_pos(test_external::ext_buffer* buffer, std::size_t pos) {
protozero_assert(pos <= buffer->size());
return (&*buffer->begin()) + pos;
}
static void push_back(test_external::ext_buffer* buffer, char ch) {
buffer->push_back(ch);
}
};
} // namespace protozero
// The following structs are used in many tests using TEMPLATE_TEST_CASE() to
// test the different buffer types:
//
// 1. Dynamically sized buffer based on std::string.
// 2. Dynamically sized buffer based on std::vector<char>.
// 3. Statically sized buffer based on std::array<char, N>.
// 4. Externally defined buffer.
class buffer_test_string {
std::string m_buffer;
public:
using type = std::string;
using writer_type = protozero::pbf_writer; // == protozero::basic_pbf_writer<type>;
type& buffer() noexcept {
return m_buffer;
}
const char *data() const noexcept {
return m_buffer.data();
}
std::size_t size() const noexcept {
return m_buffer.size();
}
}; // class buffer_test_string
class buffer_test_vector {
std::vector<char> m_buffer;
public:
using type = std::vector<char>;
using writer_type = protozero::basic_pbf_writer<type>;
type& buffer() noexcept {
return m_buffer;
}
const char *data() const noexcept {
return m_buffer.data();
}
std::size_t size() const noexcept {
return m_buffer.size();
}
}; // class buffer_test_vector
class buffer_test_array {
public:
using type = protozero::fixed_size_buffer_adaptor;
using writer_type = protozero::basic_pbf_writer<type>;
type& buffer() noexcept {
return adaptor;
}
const char *data() const noexcept {
return adaptor.data();
}
std::size_t size() const noexcept {
return adaptor.size();
}
private:
std::array<char, 1024> m_buffer = {{0}};
type adaptor{m_buffer};
}; // class buffer_test_array
class buffer_test_external {
test_external::ext_buffer m_buffer;
public:
using type = test_external::ext_buffer;
using writer_type = protozero::basic_pbf_writer<type>;
type& buffer() noexcept {
return m_buffer;
}
const char *data() const noexcept {
return m_buffer.data();
}
std::size_t size() const noexcept {
return m_buffer.size();
}
}; // class buffer_test_external
#endif // BUFFER_HPP

View File

@ -1,5 +1,8 @@
// NOLINT(llvm-header-guard)
#include <array>
#include <sstream>
#define PBF_TYPE_NAME PROTOZERO_TEST_STRING(PBF_TYPE)
#define GET_TYPE PROTOZERO_TEST_CONCAT(get_packed_, PBF_TYPE)
#define ADD_TYPE PROTOZERO_TEST_CONCAT(add_packed_, PBF_TYPE)
@ -92,7 +95,7 @@ TEST_CASE("read repeated packed field: " PBF_TYPE_NAME) {
for (std::string::size_type i = 1; i < abuffer.size() - n; ++i) {
protozero::pbf_reader item{abuffer.data() + n, i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.GET_TYPE(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.GET_TYPE(), protozero::end_of_buffer_exception);
}
}
@ -105,21 +108,27 @@ TEST_CASE("write repeated packed field: " PBF_TYPE_NAME) {
protozero::pbf_writer pw{buffer};
SECTION("empty") {
cpp_type data[] = { 17 };
std::array<cpp_type, 1> data = {{ 17 }};
pw.ADD_TYPE(1, std::begin(data), std::begin(data) /* !!!! */);
REQUIRE(buffer == load_data("repeated_packed_" PBF_TYPE_NAME "/data-empty"));
}
SECTION("one") {
cpp_type data[] = { 17 };
std::array<cpp_type, 1> data = {{ 17 }};
pw.ADD_TYPE(1, std::begin(data), std::end(data));
REQUIRE(buffer == load_data("repeated_packed_" PBF_TYPE_NAME "/data-one"));
}
SECTION("many") {
cpp_type data[] = {
std::array<cpp_type,
#if PBF_TYPE_IS_SIGNED
8
#else
5
#endif
> data = {{
17
, 200
, 0
@ -130,7 +139,7 @@ TEST_CASE("write repeated packed field: " PBF_TYPE_NAME) {
, -1
,std::numeric_limits<cpp_type>::min()
#endif
};
}};
pw.ADD_TYPE(1, std::begin(data), std::end(data));
REQUIRE(buffer == load_data("repeated_packed_" PBF_TYPE_NAME "/data-many"));
@ -246,9 +255,9 @@ TEST_CASE("write from different types of iterators: " PBF_TYPE_NAME) {
SECTION("from uint16_t") {
#if PBF_TYPE_IS_SIGNED
const int16_t data[] = { 1, 4, 9, 16, 25 };
const std::array< int16_t, 5> data = {{ 1, 4, 9, 16, 25 }};
#else
const uint16_t data[] = { 1, 4, 9, 16, 25 };
const std::array<uint16_t, 5> data = {{ 1, 4, 9, 16, 25 }};
#endif
pw.ADD_TYPE(1, std::begin(data), std::end(data));
@ -290,7 +299,7 @@ TEST_CASE("write from different types of iterators: " PBF_TYPE_NAME) {
REQUIRE(std::distance(it_range.begin(), it_range.end()) == 0);
REQUIRE(it_range.size() == 0); // NOLINT(readability-container-size-empty)
REQUIRE_THROWS_AS(it_range.front(), const assert_error&);
REQUIRE_THROWS_AS(it_range.drop_front(), const assert_error&);
REQUIRE_THROWS_AS(it_range.front(), assert_error);
REQUIRE_THROWS_AS(it_range.drop_front(), assert_error);
}

View File

@ -88,7 +88,7 @@ TEST_CASE("read field: " PBF_TYPE_NAME) {
for (std::string::size_type i = 1; i < buffer.size(); ++i) {
protozero::pbf_reader item{buffer.data(), i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.GET_TYPE(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.GET_TYPE(), protozero::end_of_buffer_exception);
}
}
}

View File

@ -3,6 +3,9 @@
#include <catch.hpp>
#include <array>
#include <vector>
#include <stdexcept>
// Define protozero_assert() to throw this error. This allows the tests to
// check that the assert fails.

View File

@ -1,5 +1,7 @@
#include <cstdlib>
#include <fstream>
#include <iterator>
#include <stdexcept>
#include <string>

View File

@ -47,7 +47,7 @@ TEST_CASE("check alignment issues for fixed32 field") {
for (std::string::size_type i = 1; i < abuffer.size() - n; ++i) {
protozero::pbf_reader item{abuffer.data() + n, i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_fixed32(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_fixed32(), protozero::end_of_buffer_exception);
}
}
@ -55,7 +55,7 @@ TEST_CASE("check alignment issues for fixed32 field") {
abuffer.append(load_data("fixed32/data-zero"));
protozero::pbf_reader item{abuffer.data() + n, abuffer.size() - n};
REQUIRE_THROWS_AS(item.get_fixed32(), const assert_error&);
REQUIRE_THROWS_AS(item.get_fixed32(), assert_error);
REQUIRE(item.next());
REQUIRE(item.get_fixed32() == 0UL);
REQUIRE_THROWS(item.get_fixed32());
@ -66,7 +66,7 @@ TEST_CASE("check alignment issues for fixed32 field") {
abuffer.append(load_data("fixed32/data-zero"));
protozero::pbf_reader item{abuffer.data() + n, abuffer.size() - n};
REQUIRE_THROWS_AS(item.skip(), const assert_error&);
REQUIRE_THROWS_AS(item.skip(), assert_error);
REQUIRE(item.next());
item.skip();
REQUIRE_THROWS(item.skip());
@ -114,7 +114,7 @@ TEST_CASE("check alignment issues for fixed64 field") {
for (std::string::size_type i = 1; i < abuffer.size() - n; ++i) {
protozero::pbf_reader item{abuffer.data() + n, i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_fixed64(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_fixed64(), protozero::end_of_buffer_exception);
}
}
}

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -126,7 +126,7 @@ TEST_CASE("write bool field using moved pbf_builder") {
protozero::pbf_builder<TestBoolean::Test> pw{std::move(pw2)};
REQUIRE(pw.valid());
REQUIRE_FALSE(pw2.valid()); // NOLINT(hicpp-invalid-access-moved, bugprone-use-after-move)
REQUIRE_FALSE(pw2.valid()); // NOLINT(hicpp-invalid-access-moved, bugprone-use-after-move, clang-analyzer-cplusplus.Move)
SECTION("false") {
pw.add_bool(TestBoolean::Test::required_bool_b, false);

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestBoolean::Test msg;
msg.set_b(0);

View File

@ -1,21 +1,22 @@
#include <string>
#include <test.hpp> // IWYU pragma: keep
#include <buffer.hpp>
#include "t/bool/bool_testcase.pb.h"
TEST_CASE("write bool field and check with libprotobuf") {
TEMPLATE_TEST_CASE("write bool field and check with libprotobuf", "",
buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
std::string buffer;
protozero::pbf_writer pw{buffer};
TestType buffer;
typename TestType::writer_type pw{buffer.buffer()};
TestBoolean::Test msg;
SECTION("false") {
pw.add_bool(1, false);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE_FALSE(msg.b());
}
@ -23,7 +24,7 @@ TEST_CASE("write bool field and check with libprotobuf") {
SECTION("true") {
pw.add_bool(1, true);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.b());
}

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -51,7 +51,7 @@ TEST_CASE("read bytes field: end of buffer") {
for (std::string::size_type i = 1; i < buffer.size(); ++i) {
protozero::pbf_reader item{buffer.data(), i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_bytes(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_bytes(), protozero::end_of_buffer_exception);
}
}

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestBytes::Test msg;
msg.set_s("");

View File

@ -1,19 +1,20 @@
#include <test.hpp>
#include <buffer.hpp>
#include "t/bytes/bytes_testcase.pb.h"
TEST_CASE("write bytes field and check with libprotobuf") {
TEMPLATE_TEST_CASE("write bytes field and check with libprotobuf", "",
buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
std::string buffer;
protozero::pbf_writer pw{buffer};
TestType buffer;
typename TestType::writer_type pw{buffer.buffer()};
TestBytes::Test msg;
SECTION("empty") {
pw.add_string(1, "");
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.s().empty());
}
@ -21,7 +22,7 @@ TEST_CASE("write bytes field and check with libprotobuf") {
SECTION("one") {
pw.add_string(1, "x");
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.s() == "x");
}
@ -29,7 +30,7 @@ TEST_CASE("write bytes field and check with libprotobuf") {
SECTION("string") {
pw.add_string(1, "foobar");
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.s() == "foobar");
}
@ -42,7 +43,7 @@ TEST_CASE("write bytes field and check with libprotobuf") {
pw.add_string(1, data);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.s().size() == 3);
REQUIRE(msg.s()[1] == char(2));

View File

@ -1,6 +1,12 @@
#include <test.hpp>
#include <protozero/buffer_fixed.hpp>
#include <algorithm>
#include <array>
#include <numeric>
namespace TestComplex {
enum class Test : protozero::pbf_tag_type {
@ -120,11 +126,7 @@ TEST_CASE("read complex data using pbf_reader: all") {
}
case 7: {
const auto pi = item.get_packed_sint32();
int32_t sum = 0;
for (auto val : pi) {
sum += val;
}
REQUIRE(sum == 5);
REQUIRE(std::accumulate(pi.cbegin(), pi.cend(), 0) == 5);
break;
}
case 8: {
@ -265,11 +267,7 @@ TEST_CASE("read complex data using pbf_message: all") {
}
case TestComplex::Test::packed_sint32_d: {
const auto pi = item.get_packed_sint32();
int32_t sum = 0;
for (auto val : pi) {
sum += val;
}
REQUIRE(sum == 5);
REQUIRE(std::accumulate(pi.cbegin(), pi.cend(), 0) == 5);
break;
}
case TestComplex::Test::optional_string_s: {
@ -416,7 +414,7 @@ TEST_CASE("write complex data using pbf_writer: all") {
pw.add_uint32(4, 66);
pw.add_uint32(4, 66);
const int32_t d[] = { -17, 22 };
const std::array<int32_t, 2> d = {{ -17, 22 }};
pw.add_packed_sint32(7, std::begin(d), std::end(d));
pw.add_int64(3, 555555555);
@ -453,15 +451,7 @@ TEST_CASE("write complex data using pbf_writer: all") {
}
case 7: {
const auto pi = item.get_packed_sint32();
int32_t sum = 0;
for (auto val : pi) {
sum += val;
}
REQUIRE(sum == 5);
break;
}
case 8: {
REQUIRE(item.get_string() == "optionalstring");
REQUIRE(std::accumulate(pi.cbegin(), pi.cend(), 0) == 5);
break;
}
default: {
@ -577,7 +567,7 @@ TEST_CASE("write complex data using pbf_builder: all") {
pw.add_uint32(TestComplex::Test::repeated_uint32_u, 66);
pw.add_uint32(TestComplex::Test::repeated_uint32_u, 66);
const int32_t d[] = { -17, 22 };
const std::array<int32_t, 2> d = {{ -17, 22 }};
pw.add_packed_sint32(TestComplex::Test::packed_sint32_d, std::begin(d), std::end(d));
pw.add_int64(TestComplex::Test::optional_int64_j, 555555555);
@ -614,15 +604,7 @@ TEST_CASE("write complex data using pbf_builder: all") {
}
case 7: {
const auto pi = item.get_packed_sint32();
int32_t sum = 0;
for (auto val : pi) {
sum += val;
}
REQUIRE(sum == 5);
break;
}
case 8: {
REQUIRE(item.get_string() == "optionalstring");
REQUIRE(std::accumulate(pi.cbegin(), pi.cend(), 0) == 5);
break;
}
default: {
@ -684,3 +666,77 @@ TEST_CASE("write complex with subwriter using pbf_builder") {
check_message(buffer_test);
}
TEST_CASE("write complex data using basic_pbf_writer<fixed_size_buffer_adaptor>: all") {
std::string data;
data.resize(10240);
protozero::fixed_size_buffer_adaptor buffer{&*data.begin(), data.size()};
protozero::basic_pbf_writer<protozero::fixed_size_buffer_adaptor> pw{buffer};
pw.add_fixed32(1, 12345678);
std::string sdata;
sdata.resize(10240);
protozero::fixed_size_buffer_adaptor submessage{&*sdata.begin(), sdata.size()};
protozero::basic_pbf_writer<protozero::fixed_size_buffer_adaptor> pws{submessage};
pws.add_string(1, "foobar");
pw.add_message(5, submessage.data(), submessage.size());
pw.add_uint32(4, 22);
pw.add_uint32(4, 44);
pw.add_int64(2, -9876543);
pw.add_uint32(4, 44);
pw.add_uint32(4, 66);
pw.add_uint32(4, 66);
const std::array<int32_t, 2> d = {{ -17, 22 }};
pw.add_packed_sint32(7, std::begin(d), std::end(d));
pw.add_int64(3, 555555555);
protozero::pbf_reader item{buffer.data(), buffer.size()};
int number_of_u = 0;
while (item.next()) {
switch (item.tag()) {
case 1: {
REQUIRE(item.get_fixed32() == 12345678L);
break;
}
case 2: {
REQUIRE(true);
item.skip();
break;
}
case 3: {
REQUIRE(item.get_int64() == 555555555LL);
break;
}
case 4: {
item.skip();
++number_of_u;
break;
}
case 5: {
protozero::pbf_reader subitem = item.get_message();
REQUIRE(subitem.next());
REQUIRE(subitem.get_string() == "foobar");
REQUIRE_FALSE(subitem.next());
break;
}
case 7: {
const auto pi = item.get_packed_sint32();
REQUIRE(std::accumulate(pi.cbegin(), pi.cend(), 0) == 5);
break;
}
case 8: {
REQUIRE(item.get_string() == "optionalstring");
break;
}
default: {
REQUIRE(false); // should not be here
break;
}
}
}
REQUIRE(number_of_u == 5);
}

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestComplex::Test msg;
msg.set_f(12345678);

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -45,7 +45,7 @@ TEST_CASE("read double field") {
for (std::string::size_type i = 1; i < abuffer.size() - n; ++i) {
protozero::pbf_reader item{abuffer.data() + n, i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_double(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_double(), protozero::end_of_buffer_exception);
}
}
}

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestDouble::Test msg;
msg.set_x(0.0);

View File

@ -1,19 +1,20 @@
#include <test.hpp>
#include <buffer.hpp>
#include "t/double/double_testcase.pb.h"
TEST_CASE("write double field and check with libprotobuf") {
TEMPLATE_TEST_CASE("write double field and check with libprotobuf", "",
buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
std::string buffer;
protozero::pbf_writer pw{buffer};
TestType buffer;
typename TestType::writer_type pw{buffer.buffer()};
TestDouble::Test msg;
SECTION("zero") {
pw.add_double(1, 0.0);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.x() == Approx(0.0));
}
@ -21,7 +22,7 @@ TEST_CASE("write double field and check with libprotobuf") {
SECTION("positive") {
pw.add_double(1, 4.893);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.x() == Approx(4.893));
}
@ -29,7 +30,7 @@ TEST_CASE("write double field and check with libprotobuf") {
SECTION("negative") {
pw.add_double(1, -9232.33);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.x() == Approx(-9232.33));
}

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestEnum::Test msg;
msg.set_color(TestEnum::BLACK);

View File

@ -1,19 +1,20 @@
#include <test.hpp>
#include <buffer.hpp>
#include "t/enum/enum_testcase.pb.h"
TEST_CASE("write enum field and check with libprotobuf") {
TEMPLATE_TEST_CASE("write enum field and check with libprotobuf", "",
buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
std::string buffer;
protozero::pbf_writer pw{buffer};
TestType buffer;
typename TestType::writer_type pw{buffer.buffer()};
TestEnum::Test msg;
SECTION("zero") {
pw.add_enum(1, 0L);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.color() == TestEnum::Color::BLACK);
}
@ -21,7 +22,7 @@ TEST_CASE("write enum field and check with libprotobuf") {
SECTION("positive") {
pw.add_enum(1, 3L);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.color() == TestEnum::Color::BLUE);
}
@ -29,7 +30,7 @@ TEST_CASE("write enum field and check with libprotobuf") {
SECTION("negative") {
pw.add_enum(1, -1L);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.color() == TestEnum::Color::NEG);
}
@ -37,7 +38,7 @@ TEST_CASE("write enum field and check with libprotobuf") {
SECTION("max") {
pw.add_enum(1, std::numeric_limits<int32_t>::max() - 1);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.color() == TestEnum::Color::MAX);
}
@ -45,7 +46,7 @@ TEST_CASE("write enum field and check with libprotobuf") {
SECTION("min") {
pw.add_enum(1, std::numeric_limits<int32_t>::min() + 1);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.color() == TestEnum::Color::MIN);
}

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestFixed32::Test msg;
msg.set_i(0);

View File

@ -1,19 +1,20 @@
#include <test.hpp>
#include <buffer.hpp>
#include "t/fixed32/fixed32_testcase.pb.h"
TEST_CASE("write fixed32 field and check with libprotobuf") {
TEMPLATE_TEST_CASE("write fixed32 field and check with libprotobuf", "",
buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
std::string buffer;
protozero::pbf_writer pw{buffer};
TestType buffer;
typename TestType::writer_type pw{buffer.buffer()};
TestFixed32::Test msg;
SECTION("zero") {
pw.add_fixed32(1, 0);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i() == 0);
}
@ -21,7 +22,7 @@ TEST_CASE("write fixed32 field and check with libprotobuf") {
SECTION("max") {
pw.add_fixed32(1, std::numeric_limits<uint32_t>::max());
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i() == std::numeric_limits<uint32_t>::max());
}
@ -29,7 +30,7 @@ TEST_CASE("write fixed32 field and check with libprotobuf") {
SECTION("min") {
pw.add_fixed32(1, std::numeric_limits<uint32_t>::min());
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i() == std::numeric_limits<uint32_t>::min());
}

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestFixed64::Test msg;
msg.set_i(0);

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -46,7 +46,7 @@ TEST_CASE("read float field") {
for (std::string::size_type i = 1; i < abuffer.size() - n; ++i) {
protozero::pbf_reader item{abuffer.data() + n, i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_float(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_float(), protozero::end_of_buffer_exception);
}
}
}
@ -57,17 +57,17 @@ TEST_CASE("write float field") {
protozero::pbf_writer pw{buffer};
SECTION("zero") {
pw.add_float(1, 0.0f);
pw.add_float(1, 0.0F);
REQUIRE(buffer == load_data("float/data-zero"));
}
SECTION("positive") {
pw.add_float(1, 5.34f);
pw.add_float(1, 5.34F);
REQUIRE(buffer == load_data("float/data-pos"));
}
SECTION("negative") {
pw.add_float(1, -1.71f);
pw.add_float(1, -1.71F);
REQUIRE(buffer == load_data("float/data-neg"));
}
}

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestFloat::Test msg;
msg.set_x(0.0);

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestInt32::Test msg;
msg.set_i(0);

View File

@ -1,19 +1,20 @@
#include <test.hpp>
#include <buffer.hpp>
#include "t/int32/int32_testcase.pb.h"
TEST_CASE("write int32 field and check with libprotobuf") {
TEMPLATE_TEST_CASE("write int32 field and check with libprotobuf", "",
buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
std::string buffer;
protozero::pbf_writer pw{buffer};
TestType buffer;
typename TestType::writer_type pw{buffer.buffer()};
TestInt32::Test msg;
SECTION("zero") {
pw.add_int32(1, 0L);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i() == 0L);
}
@ -21,7 +22,7 @@ TEST_CASE("write int32 field and check with libprotobuf") {
SECTION("positive") {
pw.add_int32(1, 1L);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i() == 1L);
}
@ -29,7 +30,7 @@ TEST_CASE("write int32 field and check with libprotobuf") {
SECTION("negative") {
pw.add_int32(1, -1L);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i() == -1L);
}
@ -37,7 +38,7 @@ TEST_CASE("write int32 field and check with libprotobuf") {
SECTION("max") {
pw.add_int32(1, std::numeric_limits<int32_t>::max());
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i() == std::numeric_limits<int32_t>::max());
}
@ -45,7 +46,7 @@ TEST_CASE("write int32 field and check with libprotobuf") {
SECTION("min") {
pw.add_int32(1, std::numeric_limits<int32_t>::min());
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i() == std::numeric_limits<int32_t>::min());
}

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestInt64::Test msg;
msg.set_i(0);

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -6,10 +6,16 @@ TEST_CASE("read message field: string") {
protozero::pbf_reader item{buffer};
REQUIRE(item.data().data() == buffer.data());
REQUIRE(item.data().size() == buffer.size());
REQUIRE(item.next());
protozero::pbf_reader subitem{item.get_message()};
REQUIRE_FALSE(item.next());
REQUIRE(item.data().data() == buffer.data() + buffer.size());
REQUIRE(item.data().empty());
REQUIRE(subitem.next());
REQUIRE(subitem.get_string() == "foobar");
REQUIRE_FALSE(subitem.next());
@ -21,7 +27,7 @@ TEST_CASE("read message field: end of buffer") {
for (std::string::size_type i = 1; i < buffer.size(); ++i) {
protozero::pbf_reader item{buffer.data(), i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_string(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_string(), protozero::end_of_buffer_exception);
}
}

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestMessage::Test msg;
TestMessage::Sub* submsg = msg.mutable_submessage();

View File

@ -1,28 +1,29 @@
#include <test.hpp>
#include <buffer.hpp>
#include "t/message/message_testcase.pb.h"
TEST_CASE("write message field and check with libprotobuf") {
TEMPLATE_TEST_CASE("write message field and check with libprotobuf", "",
buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
std::string buffer_test;
protozero::pbf_writer pbf_test{buffer_test};
TestType buffer;
typename TestType::writer_type pw{buffer.buffer()};
SECTION("string") {
std::string buffer_submessage;
protozero::pbf_writer pbf_submessage{buffer_submessage};
pbf_submessage.add_string(1, "foobar");
pbf_test.add_message(1, buffer_submessage);
pw.add_message(1, buffer_submessage);
}
SECTION("string with subwriter") {
protozero::pbf_writer pbf_submessage{pbf_test, 1};
typename TestType::writer_type pbf_submessage{pw, 1};
pbf_submessage.add_string(1, "foobar");
}
TestMessage::Test msg;
msg.ParseFromString(buffer_test);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.submessage().s() == "foobar");
}

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestNested::Test msg;
msg.set_i(77);

View File

@ -1,12 +1,13 @@
#include <test.hpp>
#include <buffer.hpp>
#include "t/nested/nested_testcase.pb.h"
TEST_CASE("write nested message fields and check with libprotobuf") {
TEMPLATE_TEST_CASE("write nested message fields and check with libprotobuf", "",
buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
std::string buffer_test;
protozero::pbf_writer pbf_test{buffer_test};
TestType buffer;
typename TestType::writer_type pw{buffer.buffer()};
SECTION("string") {
std::string buffer_subsub;
@ -19,23 +20,23 @@ TEST_CASE("write nested message fields and check with libprotobuf") {
pbf_sub.add_string(1, buffer_subsub);
pbf_sub.add_int32(2, 88);
pbf_test.add_message(1, buffer_sub);
pw.add_message(1, buffer_sub);
}
SECTION("with subwriter") {
protozero::pbf_writer pbf_sub{pbf_test, 1};
typename TestType::writer_type pbf_sub{pw, 1};
{
protozero::pbf_writer pbf_subsub(pbf_sub, 1);
typename TestType::writer_type pbf_subsub(pbf_sub, 1);
pbf_subsub.add_string(1, "foobar");
pbf_subsub.add_int32(2, 99);
}
pbf_sub.add_int32(2, 88);
}
pbf_test.add_int32(2, 77);
pw.add_int32(2, 77);
TestNested::Test msg;
msg.ParseFromString(buffer_test);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i() == 77);
REQUIRE(msg.sub().i() == 88);

View File

@ -48,7 +48,7 @@ TEST_CASE("read repeated fields: end of buffer") {
for (std::string::size_type i = 1; i < buffer.size(); ++i) {
protozero::pbf_reader item{buffer.data(), i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_int32(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_int32(), protozero::end_of_buffer_exception);
}
}

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeated::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,19 +1,20 @@
#include <test.hpp>
#include <buffer.hpp>
#include "t/repeated/repeated_testcase.pb.h"
TEST_CASE("write repeated fields and check with libprotobuf") {
TEMPLATE_TEST_CASE("write repeated fields and check with libprotobuf", "",
buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
std::string buffer;
protozero::pbf_writer pw{buffer};
TestType buffer;
typename TestType::writer_type pw{buffer.buffer()};
TestRepeated::Test msg;
SECTION("one") {
pw.add_int32(1, 0L);
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i().size() == 1);
REQUIRE(msg.i(0) == 0L);
@ -26,7 +27,7 @@ TEST_CASE("write repeated fields and check with libprotobuf") {
pw.add_int32(1, std::numeric_limits<int32_t>::max());
pw.add_int32(1, std::numeric_limits<int32_t>::min());
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i().size() == 5);
REQUIRE(msg.i(0) == 0L);

View File

@ -1,6 +1,8 @@
#include <test.hpp>
#include <array>
TEST_CASE("read repeated packed bool field: empty") {
const std::string buffer = load_data("repeated_packed_bool/data-empty");
@ -51,7 +53,7 @@ TEST_CASE("read repeated packed bool field: end of buffer") {
for (std::string::size_type i = 1; i < buffer.size(); ++i) {
protozero::pbf_reader item{buffer.data(), i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_packed_bool(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_packed_bool(), protozero::end_of_buffer_exception);
}
}
@ -60,21 +62,21 @@ TEST_CASE("write repeated packed bool field") {
protozero::pbf_writer pw{buffer};
SECTION("empty") {
const bool data[] = { true };
const std::array<bool, 1> data = {{ true }};
pw.add_packed_bool(1, std::begin(data), std::begin(data) /* !!!! */);
REQUIRE(buffer == load_data("repeated_packed_bool/data-empty"));
}
SECTION("one") {
const bool data[] = { true };
const std::array<bool, 1> data = {{ true }};
pw.add_packed_bool(1, std::begin(data), std::end(data));
REQUIRE(buffer == load_data("repeated_packed_bool/data-one"));
}
SECTION("many") {
const bool data[] = { true, true, false, true };
const std::array<bool, 4> data = {{ true, true, false, true }};
pw.add_packed_bool(1, std::begin(data), std::end(data));
REQUIRE(buffer == load_data("repeated_packed_bool/data-many"));

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedBool::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,6 +1,8 @@
#include <test.hpp>
#include <array>
TEST_CASE("read repeated packed double field") {
// Run these tests twice, the second time we basically move the data
// one byte down in the buffer. It doesn't matter how the data or buffer
@ -82,7 +84,7 @@ TEST_CASE("read repeated packed double field") {
for (std::string::size_type i = 1; i < abuffer.size() - n; ++i) {
protozero::pbf_reader item{abuffer.data() + n, i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_packed_double(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_packed_double(), protozero::end_of_buffer_exception);
}
}
}
@ -93,21 +95,23 @@ TEST_CASE("write repeated packed double field") {
protozero::pbf_writer pw{buffer};
SECTION("empty") {
const double data[] = { 17.34 };
const std::array<double, 1> data = {{ 17.34 }};
pw.add_packed_double(1, std::begin(data), std::begin(data) /* !!!! */);
REQUIRE(buffer == load_data("repeated_packed_double/data-empty"));
}
SECTION("one") {
const double data[] = { 17.34 };
const std::array<double, 1> data = {{ 17.34 }};
pw.add_packed_double(1, std::begin(data), std::end(data));
REQUIRE(buffer == load_data("repeated_packed_double/data-one"));
}
SECTION("many") {
const double data[] = { 17.34, 0.0, 1.0, std::numeric_limits<double>::min(), std::numeric_limits<double>::max() };
const std::array<double, 5> data = {{ 17.34, 0.0, 1.0,
std::numeric_limits<double>::min(),
std::numeric_limits<double>::max() }};
pw.add_packed_double(1, std::begin(data), std::end(data));
REQUIRE(buffer == load_data("repeated_packed_double/data-many"));

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedDouble::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,6 +1,8 @@
#include <test.hpp>
#include <array>
TEST_CASE("read repeated packed enum field: empty") {
const std::string buffer = load_data("repeated_packed_enum/data-empty");
@ -46,7 +48,7 @@ TEST_CASE("read repeated packed enum field: end of buffer") {
for (std::string::size_type i = 1; i < buffer.size(); ++i) {
protozero::pbf_reader item{buffer.data(), i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_packed_enum(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_packed_enum(), protozero::end_of_buffer_exception);
}
}
@ -55,21 +57,21 @@ TEST_CASE("write repeated packed enum field") {
protozero::pbf_writer pw{buffer};
SECTION("empty") {
const int32_t data[] = { 0 /* BLACK */ };
const std::array<int32_t, 1> data = {{ 0 /* BLACK */ }};
pw.add_packed_enum(1, std::begin(data), std::begin(data) /* !!!! */);
REQUIRE(buffer == load_data("repeated_packed_enum/data-empty"));
}
SECTION("one") {
const int32_t data[] = { 0 /* BLACK */ };
const std::array<int32_t, 1> data = {{ 0 /* BLACK */ }};
pw.add_packed_enum(1, std::begin(data), std::end(data));
REQUIRE(buffer == load_data("repeated_packed_enum/data-one"));
}
SECTION("many") {
const int32_t data[] = { 0 /* BLACK */, 3 /* BLUE */, 2 /* GREEN */ };
const std::array<int32_t, 3> data = {{ 0 /* BLACK */, 3 /* BLUE */, 2 /* GREEN */ }};
pw.add_packed_enum(1, std::begin(data), std::end(data));
REQUIRE(buffer == load_data("repeated_packed_enum/data-many"));

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedEnum::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,3 +1,4 @@
syntax = "proto2";
option optimize_for = LITE_RUNTIME;

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedFixed32::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,35 +1,39 @@
#include <test.hpp>
#include <buffer.hpp>
#include <array>
#include <sstream>
#include "t/repeated_packed_fixed32/repeated_packed_fixed32_testcase.pb.h"
TEST_CASE("write repeated packed fixed32 field and check with libprotobuf") {
TEMPLATE_TEST_CASE("write repeated packed fixed32 field and check with libprotobuf", "",
buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
std::string buffer;
protozero::pbf_writer pw{buffer};
TestType buffer;
typename TestType::writer_type pw{buffer.buffer()};
TestRepeatedPackedFixed32::Test msg;
SECTION("empty") {
uint32_t data[] = { 17UL };
const std::array<uint32_t, 1> data = {{ 17UL }};
pw.add_packed_fixed32(1, std::begin(data), std::begin(data) /* !!!! */);
}
SECTION("one") {
uint32_t data[] = { 17UL };
const std::array<uint32_t, 1> data = {{ 17UL }};
pw.add_packed_fixed32(1, std::begin(data), std::end(data));
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i().size() == 1);
REQUIRE(msg.i(0) == 17UL);
}
SECTION("many") {
uint32_t data[] = { 17UL, 0UL, 1UL, std::numeric_limits<uint32_t>::max() };
const std::array<uint32_t, 4> data = {{ 17UL, 0UL, 1UL, std::numeric_limits<uint32_t>::max() }};
pw.add_packed_fixed32(1, std::begin(data), std::end(data));
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i().size() == 4);
REQUIRE(msg.i(0) == 17UL);
@ -39,17 +43,18 @@ TEST_CASE("write repeated packed fixed32 field and check with libprotobuf") {
}
}
TEST_CASE("write from different types of iterators and check with libprotobuf") {
TEMPLATE_TEST_CASE("write from different types of iterators and check with libprotobuf", "",
buffer_test_string, buffer_test_vector, buffer_test_array, buffer_test_external) {
std::string buffer;
protozero::pbf_writer pw{buffer};
TestType buffer;
typename TestType::writer_type pw{buffer.buffer()};
TestRepeatedPackedFixed32::Test msg;
SECTION("from uint16_t") {
uint16_t data[] = { 1, 4, 9, 16, 25 };
const std::array<uint16_t, 5> data = {{ 1, 4, 9, 16, 25 }};
pw.add_packed_fixed32(1, std::begin(data), std::end(data));
pw.template add_packed_fixed<uint32_t>(1, std::begin(data), std::end(data));
}
SECTION("from string") {
@ -59,10 +64,10 @@ TEST_CASE("write from different types of iterators and check with libprotobuf")
std::istream_iterator<uint32_t> eod;
std::istream_iterator<uint32_t> it(sdata);
pw.add_packed_fixed32(1, it, eod);
pw.template add_packed_fixed<uint32_t>(1, it, eod);
}
msg.ParseFromString(buffer);
msg.ParseFromArray(buffer.data(), buffer.size());
REQUIRE(msg.i().size() == 5);
REQUIRE(msg.i(0) == 1);

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedFixed64::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,6 +1,8 @@
#include <test.hpp>
#include <array>
TEST_CASE("read repeated packed float field") {
// Run these tests twice, the second time we basically move the data
// one byte down in the buffer. It doesn't matter how the data or buffer
@ -28,7 +30,7 @@ TEST_CASE("read repeated packed float field") {
auto it_range = item.get_packed_float();
REQUIRE_FALSE(item.next());
REQUIRE(*it_range.begin() == Approx(17.34f));
REQUIRE(*it_range.begin() == Approx(17.34F));
REQUIRE(std::next(it_range.begin()) == it_range.end());
}
@ -41,9 +43,9 @@ TEST_CASE("read repeated packed float field") {
REQUIRE_FALSE(item.next());
auto it = it_range.begin();
REQUIRE(*it++ == Approx(17.34f));
REQUIRE(*it++ == Approx( 0.0f));
REQUIRE(*it++ == Approx( 1.0f));
REQUIRE(*it++ == Approx(17.34F));
REQUIRE(*it++ == Approx( 0.0F));
REQUIRE(*it++ == Approx( 1.0F));
REQUIRE(*it++ == std::numeric_limits<float>::min());
REQUIRE(*it++ == std::numeric_limits<float>::max());
REQUIRE(it == it_range.end());
@ -55,7 +57,7 @@ TEST_CASE("read repeated packed float field") {
for (std::string::size_type i = 1; i < abuffer.size() - n; ++i) {
protozero::pbf_reader item{abuffer.data() + n, i};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_packed_float(), const protozero::end_of_buffer_exception&);
REQUIRE_THROWS_AS(item.get_packed_float(), protozero::end_of_buffer_exception);
}
}
}
@ -66,21 +68,21 @@ TEST_CASE("write repeated packed float field") {
protozero::pbf_writer pw{buffer};
SECTION("empty") {
float data[] = { 17.34f };
const std::array<float, 1> data = {{ 17.34F }};
pw.add_packed_float(1, std::begin(data), std::begin(data) /* !!!! */);
REQUIRE(buffer == load_data("repeated_packed_float/data-empty"));
}
SECTION("one") {
float data[] = { 17.34f };
const std::array<float, 1> data = {{ 17.34F }};
pw.add_packed_float(1, std::begin(data), std::end(data));
REQUIRE(buffer == load_data("repeated_packed_float/data-one"));
}
SECTION("many") {
float data[] = { 17.34f, 0.0f, 1.0f, std::numeric_limits<float>::min(), std::numeric_limits<float>::max() };
const std::array<float, 5> data = {{ 17.34F, 0.0F, 1.0F, std::numeric_limits<float>::min(), std::numeric_limits<float>::max() }};
pw.add_packed_float(1, std::begin(data), std::end(data));
REQUIRE(buffer == load_data("repeated_packed_float/data-many"));

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedFloat::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedInt32::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedInt64::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -25,6 +25,6 @@ TEST_CASE("length value must be dividable by sizeof(T)") {
protozero::pbf_reader item{data};
REQUIRE(item.next());
REQUIRE_THROWS_AS(item.get_packed_sfixed32(), const protozero::invalid_length_exception&);
REQUIRE_THROWS_AS(item.get_packed_sfixed32(), protozero::invalid_length_exception);
}

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedSFixed32::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedSFixed64::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedSInt32::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedSInt64::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedUInt32::Test msg;
write_to_file(msg, "data-empty.pbf");

View File

@ -1,8 +1,9 @@
#include <testcase.hpp>
#include "testcase.pb.h"
int main(int c, char *argv[]) {
int main() {
TestRepeatedPackedUInt64::Test msg;
write_to_file(msg, "data-empty.pbf");

Some files were not shown because too many files have changed in this diff Show More