Compare commits
174
Commits
ndn-cxx-0.7.1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ad02f3428 | ||
|
|
6d4a6536fd | ||
|
|
e58bab2e8a | ||
|
|
995c411ae4 | ||
|
|
49e1e87b24 | ||
|
|
2f46d6543e | ||
|
|
550d8c99ab | ||
|
|
e1005da0a2 | ||
|
|
6028418380 | ||
|
|
5686c51b87 | ||
|
|
c996742bad | ||
|
|
90d3a96dc2 | ||
|
|
fffdd62715 | ||
|
|
ce442c4c95 | ||
|
|
ee97139dcd | ||
|
|
03fdfb17a1 | ||
|
|
747cb45c16 | ||
|
|
9404892918 | ||
|
|
382de67df8 | ||
|
|
0af48fb516 | ||
|
|
12b8aaa9f2 | ||
|
|
502c4c3bd6 | ||
|
|
f81de71486 | ||
|
|
67bc114aa8 | ||
|
|
699cca4ba0 | ||
|
|
296c3a185d | ||
|
|
47ce2eed3a | ||
|
|
21b7f1b379 | ||
|
|
581dd52b0d | ||
|
|
152ef44da9 | ||
|
|
3fdb02f62e | ||
|
|
a3651646a9 | ||
|
|
23483c76d5 | ||
|
|
0910343957 | ||
|
|
187e9f99b2 | ||
|
|
eb87c28200 | ||
|
|
869d1a3c36 | ||
|
|
05ec0be21b | ||
|
|
f6b458930f | ||
|
|
a2fbc35f12 | ||
|
|
fcd3e44028 | ||
|
|
762548b15e | ||
|
|
02ed332ddd | ||
|
|
d09d52bdfa | ||
|
|
ae39daf4de | ||
|
|
a90b2cf762 | ||
|
|
535bd33223 | ||
|
|
81de5d98e9 | ||
|
|
15fa994bf6 | ||
|
|
67090837ab | ||
|
|
90795be569 | ||
|
|
576c21ba33 | ||
|
|
ffddbbf745 | ||
|
|
09c064f1c5 | ||
|
|
b5e95f9106 | ||
|
|
83faec7308 | ||
|
|
017a9c066f | ||
|
|
5c4f376e05 | ||
|
|
8fbffe4577 | ||
|
|
637ea3b2a9 | ||
|
|
2acce25696 | ||
|
|
ea5ce49651 | ||
|
|
e16ac8693f | ||
|
|
c860bd1ccb | ||
|
|
0f56226142 | ||
|
|
05b56a8250 | ||
|
|
02bbfa7b0f | ||
|
|
87208f964a | ||
|
|
a821f59741 | ||
|
|
73e946e2c8 | ||
|
|
f662500858 | ||
|
|
dc3575fd92 | ||
|
|
134ed4832b | ||
|
|
2d7c585965 | ||
|
|
fbca611095 | ||
|
|
80d671f996 | ||
|
|
58de07ae20 | ||
|
|
9faf34bdf4 | ||
|
|
bbe7942288 | ||
|
|
e30389c32a | ||
|
|
0e768ef03a | ||
|
|
8e2a61d357 | ||
|
|
07db0733d9 | ||
|
|
8618c1e026 | ||
|
|
487e3d3c63 | ||
|
|
78ca8aeca0 | ||
|
|
b99c711a9f | ||
|
|
56cc0d7c06 | ||
|
|
1c62884f6b | ||
|
|
4999b2eddd | ||
|
|
9ee770bdcd | ||
|
|
dd0724bd70 | ||
|
|
5b4b27f3b7 | ||
|
|
85bd6998be | ||
|
|
7d72868a2e | ||
|
|
2f92b6ea7c | ||
|
|
e727229400 | ||
|
|
d6bcdbf67e | ||
|
|
85be940ae9 | ||
|
|
5b06597e84 | ||
|
|
21ee89904f | ||
|
|
541a822ae6 | ||
|
|
258d51a6d8 | ||
|
|
0838f3dacc | ||
|
|
df8fd8a158 | ||
|
|
273ea019b6 | ||
|
|
aee2ada5f0 | ||
|
|
778ad714f0 | ||
|
|
fbea4fc83d | ||
|
|
a3d809ea54 | ||
|
|
35c6379830 | ||
|
|
5bd6c643ee | ||
|
|
e4603e1028 | ||
|
|
f135f1581b | ||
|
|
3826406a1d | ||
|
|
221a72dd70 | ||
|
|
765abc9087 | ||
|
|
d1b6f95864 | ||
|
|
21ce3ad9c2 | ||
|
|
6700044973 | ||
|
|
1bf15aef02 | ||
|
|
47a94d10dc | ||
|
|
8c1c5b1849 | ||
|
|
949075ab7b | ||
|
|
682e6b4c02 | ||
|
|
83f8d167ca | ||
|
|
94dfcf11db | ||
|
|
ea9e43ec19 | ||
|
|
2b47ac0a6f | ||
|
|
3ffae2600e | ||
|
|
09d5662f2a | ||
|
|
01cea502ca | ||
|
|
b3b9562135 | ||
|
|
2e481fc28d | ||
|
|
30ed628efa | ||
|
|
74cb28f6aa | ||
|
|
93101df38f | ||
|
|
045664345c | ||
|
|
d8e0cad339 | ||
|
|
97157b4936 | ||
|
|
f3089c3522 | ||
|
|
3f13f35987 | ||
|
|
8eecc7f1ab | ||
|
|
77c5ce85aa | ||
|
|
99431c13b5 | ||
|
|
e02d2f9f6e | ||
|
|
90b6a1b0b5 | ||
|
|
a76ea9ac7d | ||
|
|
5f6865cc73 | ||
|
|
dbe645f879 | ||
|
|
cad94b0255 | ||
|
|
39535f4493 | ||
|
|
c25e463e91 | ||
|
|
3c34ec1c4c | ||
|
|
fcf4d5186c | ||
|
|
809f754bf6 | ||
|
|
f2cae616fa | ||
|
|
09904410ca | ||
|
|
fbc2f5273e | ||
|
|
478d338253 | ||
|
|
17d4b93f04 | ||
|
|
aef53b6c26 | ||
|
|
58b9e0fdc9 | ||
|
|
5dc7560d5d | ||
|
|
861e0944f7 | ||
|
|
b08edd8d3e | ||
|
|
fe24bf8412 | ||
|
|
a86300a867 | ||
|
|
1a4a7bf2a9 | ||
|
|
0b2aa13fbf | ||
|
|
737103670a | ||
|
|
574c3f96f8 | ||
|
|
20d264e148 | ||
|
|
4c1ad4ca65 |
No files matched your search
@@ -0,0 +1,17 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.conf.sample*'
|
||||
- '*.md'
|
||||
- '.mailmap'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
Ubuntu:
|
||||
uses: named-data/actions/.github/workflows/jenkins-script-ubuntu.yml@v1
|
||||
macOS:
|
||||
uses: named-data/actions/.github/workflows/jenkins-script-macos.yml@v1
|
||||
@@ -0,0 +1,48 @@
|
||||
name: Publish Docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
- '.mailmap'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Login to ${{ env.REGISTRY }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
flavor: latest=true
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
pull: true
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
@@ -0,0 +1,21 @@
|
||||
name: Docs
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
skip-deploy:
|
||||
description: 'Skip deployment?'
|
||||
required: true
|
||||
type: boolean
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
html:
|
||||
uses: named-data/actions/.github/workflows/docs-html.yml@v1
|
||||
with:
|
||||
# Deploy only the master branch and release tags
|
||||
deploy: ${{ !inputs.skip-deploy && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/ndn-cxx-')) }}
|
||||
secrets: inherit
|
||||
man:
|
||||
uses: named-data/actions/.github/workflows/docs-man.yml@v1
|
||||
@@ -27,3 +27,4 @@ __pycache__/
|
||||
|
||||
# Other
|
||||
/VERSION.info
|
||||
/examples/example-trust-anchor.cert
|
||||
@@ -1,32 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
source .jenkins.d/util.sh
|
||||
set -eo pipefail
|
||||
|
||||
case $(uname) in
|
||||
Linux)
|
||||
if [[ -e /etc/os-release ]]; then
|
||||
source /etc/os-release
|
||||
else
|
||||
source /usr/lib/os-release
|
||||
fi
|
||||
export ID VERSION_ID
|
||||
export ID_LIKE="${ID} ${ID_LIKE} linux"
|
||||
export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
|
||||
;;
|
||||
Darwin)
|
||||
# Emulate a subset of os-release(5)
|
||||
export ID=macos
|
||||
export VERSION_ID=$(sw_vers -productVersion)
|
||||
export PATH="/usr/local/bin${PATH:+:}${PATH}"
|
||||
if [[ -x /opt/homebrew/bin/brew ]]; then
|
||||
eval "$(/opt/homebrew/bin/brew shellenv)"
|
||||
elif [[ -x /usr/local/bin/brew ]]; then
|
||||
eval "$(/usr/local/bin/brew shellenv)"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
export CACHE_DIR=${CACHE_DIR:-/tmp}
|
||||
export WAF_JOBS=${WAF_JOBS:-1}
|
||||
[[ $JOB_NAME == *"code-coverage" ]] && export DISABLE_ASAN=yes
|
||||
|
||||
nanos() {
|
||||
# Cannot use date(1) because macOS does not support %N format specifier
|
||||
python3 -c 'import time; print(int(time.time() * 1e9))'
|
||||
}
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
export DISABLE_ASAN=yes
|
||||
export DISABLE_HEADERS_CHECK=yes
|
||||
fi
|
||||
|
||||
# https://reproducible-builds.org/docs/source-date-epoch/
|
||||
export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)
|
||||
|
||||
for file in .jenkins.d/*; do
|
||||
[[ -f $file && -x $file ]] || continue
|
||||
|
||||
if [[ -n $TRAVIS ]]; then
|
||||
if [[ -n $GITHUB_ACTIONS ]]; then
|
||||
label=$(basename "$file" | sed -E 's/[[:digit:]]+-(.*)\..*/\1/')
|
||||
echo -ne "travis_fold:start:${label}\r"
|
||||
echo -ne "travis_time:start:${label}\r"
|
||||
start=$(nanos)
|
||||
echo "::group::${label}"
|
||||
fi
|
||||
|
||||
echo "\$ $file"
|
||||
"$file"
|
||||
|
||||
if [[ -n $TRAVIS ]]; then
|
||||
finish=$(nanos)
|
||||
echo -ne "travis_time:end:${label}:start=${start},finish=${finish},duration=$((finish-start)),event=${label}\r"
|
||||
echo -ne "travis_fold:end:${label}\r"
|
||||
if [[ -n $GITHUB_ACTIONS ]]; then
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
done
|
||||
+32
-32
@@ -1,38 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
set -eo pipefail
|
||||
|
||||
if has OSX $NODE_LABELS; then
|
||||
FORMULAE=(boost openssl pkg-config)
|
||||
if has OSX-10.13 $NODE_LABELS || has OSX-10.14 $NODE_LABELS; then
|
||||
FORMULAE+=(python)
|
||||
APT_PKGS=(build-essential pkg-config python3-minimal
|
||||
libboost-all-dev libssl-dev libsqlite3-dev)
|
||||
FORMULAE=(boost openssl pkg-config)
|
||||
PIP_PKGS=()
|
||||
case $JOB_NAME in
|
||||
*code-coverage)
|
||||
APT_PKGS+=(lcov python3-pip)
|
||||
PIP_PKGS+=('gcovr~=5.2')
|
||||
;;
|
||||
*Docs)
|
||||
APT_PKGS+=(doxygen graphviz python3-pip)
|
||||
FORMULAE+=(doxygen graphviz)
|
||||
PIP_PKGS+=(sphinx sphinxcontrib-doxylink)
|
||||
;;
|
||||
esac
|
||||
|
||||
set -x
|
||||
|
||||
if [[ $ID == macos ]]; then
|
||||
if [[ -n $GITHUB_ACTIONS ]]; then
|
||||
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
|
||||
fi
|
||||
|
||||
if [[ -n $TRAVIS ]]; then
|
||||
# Travis images come with a large number of pre-installed
|
||||
# brew packages, don't waste time upgrading all of them
|
||||
brew list --versions "${FORMULAE[@]}" || brew update
|
||||
for FORMULA in "${FORMULAE[@]}"; do
|
||||
brew list --versions "$FORMULA" || brew install "$FORMULA"
|
||||
done
|
||||
# Ensure /usr/local/opt/openssl exists
|
||||
brew reinstall openssl
|
||||
else
|
||||
brew update
|
||||
brew upgrade
|
||||
brew install "${FORMULAE[@]}"
|
||||
brew cleanup
|
||||
fi
|
||||
|
||||
elif has Ubuntu $NODE_LABELS; then
|
||||
brew update
|
||||
brew install --formula "${FORMULAE[@]}"
|
||||
elif [[ $ID_LIKE == *debian* ]]; then
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get -qy install g++ pkg-config python3-minimal \
|
||||
libboost-all-dev libssl-dev libsqlite3-dev
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
sudo apt-get -qy install gcovr lcov
|
||||
fi
|
||||
|
||||
elif has CentOS-8 $NODE_LABELS; then
|
||||
sudo dnf -y install gcc-c++ libasan pkgconf-pkg-config python3 \
|
||||
sudo apt-get -qy install "${APT_PKGS[@]}"
|
||||
elif [[ $ID_LIKE == *fedora* ]]; then
|
||||
sudo dnf -y install gcc-c++ libasan lld pkgconf-pkg-config python3 \
|
||||
boost-devel openssl-devel sqlite-devel
|
||||
fi
|
||||
|
||||
if (( ${#PIP_PKGS[@]} )); then
|
||||
pip3 install --user --upgrade --upgrade-strategy=eager "${PIP_PKGS[@]}"
|
||||
fi
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
|
||||
sudo rm -f /usr/local/bin/ndnsec*
|
||||
sudo rm -fr /usr/local/include/ndn-cxx
|
||||
sudo rm -f /usr/local/lib{,64}/libndn-cxx*
|
||||
sudo rm -f /usr/local/lib{,64}/pkgconfig/libndn-cxx.pc
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -exo pipefail
|
||||
|
||||
PROJ=ndn-cxx
|
||||
|
||||
sudo rm -f /usr/local/bin/ndnsec*
|
||||
sudo rm -fr /usr/local/include/"$PROJ"
|
||||
sudo rm -f /usr/local/lib{,64}/lib"$PROJ"*
|
||||
sudo rm -f /usr/local/lib{,64}/pkgconfig/{,lib}"$PROJ".pc
|
||||
+14
-13
@@ -1,8 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
|
||||
git submodule sync
|
||||
git submodule update --init
|
||||
set -eo pipefail
|
||||
|
||||
if [[ -z $DISABLE_ASAN ]]; then
|
||||
ASAN="--with-sanitizer=address"
|
||||
@@ -10,39 +7,43 @@ fi
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
COVERAGE="--with-coverage"
|
||||
fi
|
||||
if has CentOS-8 $NODE_LABELS; then
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1721553
|
||||
if [[ $ID == macos && ${VERSION_ID%%.*} -ge 12 ]]; then
|
||||
KEYCHAIN="--without-osx-keychain"
|
||||
fi
|
||||
if [[ -n $DISABLE_PCH ]]; then
|
||||
PCH="--without-pch"
|
||||
fi
|
||||
|
||||
set -x
|
||||
|
||||
if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
|
||||
# Build static library in release mode with tests and without precompiled headers
|
||||
./waf --color=yes configure --enable-static --disable-shared --with-tests --without-pch
|
||||
./waf --color=yes build -j$WAF_JOBS
|
||||
./waf --color=yes build
|
||||
|
||||
# Cleanup
|
||||
./waf --color=yes distclean
|
||||
|
||||
# Build static and shared library in release mode without tests
|
||||
./waf --color=yes configure --enable-static --enable-shared $PCH
|
||||
./waf --color=yes build -j$WAF_JOBS
|
||||
./waf --color=yes build
|
||||
|
||||
# Cleanup
|
||||
./waf --color=yes distclean
|
||||
fi
|
||||
|
||||
# Build shared library in debug mode with tests and examples
|
||||
./waf --color=yes configure --disable-static --enable-shared --debug --with-tests --with-examples $ASAN $COVERAGE $PCH
|
||||
./waf --color=yes build -j$WAF_JOBS
|
||||
./waf --color=yes configure --disable-static --enable-shared --debug --with-tests --with-examples $ASAN $COVERAGE $KEYCHAIN $PCH
|
||||
./waf --color=yes build
|
||||
|
||||
# (tests will be run against the debug version)
|
||||
|
||||
# Install
|
||||
sudo_preserve_env PATH -- ./waf --color=yes install
|
||||
sudo ./waf --color=yes install
|
||||
|
||||
if has CentOS-8 $NODE_LABELS; then
|
||||
if [[ $ID_LIKE == *fedora* ]]; then
|
||||
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
|
||||
fi
|
||||
if has Linux $NODE_LABELS; then
|
||||
if [[ $ID_LIKE == *linux* ]]; then
|
||||
sudo ldconfig
|
||||
fi
|
||||
+7
-10
@@ -1,14 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
|
||||
# Prepare environment
|
||||
rm -rf ~/.ndn
|
||||
|
||||
if has OSX $NODE_LABELS; then
|
||||
security unlock-keychain -p named-data
|
||||
fi
|
||||
|
||||
ndnsec-keygen "/tmp/jenkins/$NODE_NAME" | ndnsec-install-cert -
|
||||
set -eo pipefail
|
||||
|
||||
# https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
|
||||
ASAN_OPTIONS="color=always"
|
||||
@@ -20,10 +11,16 @@ ASAN_OPTIONS+=":detect_invalid_pointer_pairs=2"
|
||||
ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
|
||||
export ASAN_OPTIONS
|
||||
|
||||
# https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/runtime_config/summary.html
|
||||
export BOOST_TEST_BUILD_INFO=1
|
||||
export BOOST_TEST_COLOR_OUTPUT=1
|
||||
export BOOST_TEST_DETECT_MEMORY_LEAK=0
|
||||
export BOOST_TEST_LOGGER=HRF,test_suite,stdout:XML,all,build/xunit-log.xml
|
||||
|
||||
set -x
|
||||
|
||||
# Prepare environment
|
||||
rm -rf ~/.ndn
|
||||
|
||||
# Run unit tests
|
||||
./build/unit-tests
|
||||
+15
-13
@@ -1,30 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
set -exo pipefail
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
gcovr --object-directory=build \
|
||||
--output=build/coverage.xml \
|
||||
--exclude="$PWD/(examples|tests)" \
|
||||
--root=. \
|
||||
--xml
|
||||
# Generate an XML report (Cobertura format) and a detailed HTML report using gcovr
|
||||
# Note: trailing slashes are important in the paths below. Do not remove them!
|
||||
gcovr --object-directory build \
|
||||
--filter ndn-cxx/ \
|
||||
--exclude ndn-cxx/detail/nonstd/ \
|
||||
--exclude-throw-branches \
|
||||
--exclude-unreachable-branches \
|
||||
--cobertura build/coverage.xml \
|
||||
--html-details build/gcovr/ \
|
||||
--print-summary
|
||||
|
||||
# Generate also a detailed HTML output, but using lcov (better results)
|
||||
# Generate a detailed HTML report using lcov
|
||||
lcov --quiet \
|
||||
--capture \
|
||||
--directory . \
|
||||
--exclude "$PWD/ndn-cxx/detail/nonstd/*" \
|
||||
--exclude "$PWD/tests/*" \
|
||||
--no-external \
|
||||
--rc lcov_branch_coverage=1 \
|
||||
--output-file build/coverage-with-tests.info
|
||||
|
||||
lcov --quiet \
|
||||
--remove build/coverage-with-tests.info "$PWD/tests/*" \
|
||||
--rc lcov_branch_coverage=1 \
|
||||
--output-file build/coverage.info
|
||||
|
||||
genhtml --branch-coverage \
|
||||
--demangle-cpp \
|
||||
--legend \
|
||||
--output-directory build/coverage \
|
||||
--output-directory build/lcov \
|
||||
--title "ndn-cxx unit tests" \
|
||||
build/coverage.info
|
||||
fi
|
||||
@@ -1,23 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail
|
||||
# It's intentional not to use `set -x`, because this script explicitly prints useful information
|
||||
# and should not run in trace mode.
|
||||
# It's intentional not to use `set -e`, because this script wants to check all headers
|
||||
# (similar to running all test cases), instead of failing at the first error.
|
||||
|
||||
PROJ=ndn-cxx
|
||||
PCFILE=libndn-cxx
|
||||
|
||||
if [[ -n $DISABLE_HEADERS_CHECK ]]; then
|
||||
echo 'Skipping headers check.'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if has CentOS-8 $NODE_LABELS; then
|
||||
if [[ $ID_LIKE == *fedora* ]]; then
|
||||
export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
|
||||
fi
|
||||
|
||||
CXX=${CXX:-g++}
|
||||
STD=-std=c++14
|
||||
CXXFLAGS="-O2 -Wall -Wno-unneeded-internal-declaration -Wno-unused-const-variable $(pkg-config --cflags libndn-cxx)"
|
||||
INCLUDEDIR="$(pkg-config --variable=includedir libndn-cxx)"/ndn-cxx
|
||||
STD=-std=c++17
|
||||
CXXFLAGS="-O2 -Wall -Wno-unneeded-internal-declaration -Wno-unused-const-variable $(pkg-config --cflags libndn-cxx $PCFILE)"
|
||||
INCLUDEDIR="$(pkg-config --variable=includedir $PCFILE)"/$PROJ
|
||||
|
||||
echo "Using: $CXX $STD $CXXFLAGS"
|
||||
|
||||
@@ -25,13 +26,12 @@ NCHECKED=0
|
||||
NERRORS=0
|
||||
while IFS= read -r -d '' H; do
|
||||
echo "Checking header ${H#${INCLUDEDIR}/}"
|
||||
"$CXX" -xc++ $STD $CXXFLAGS -c -o /dev/null "$H"
|
||||
[[ $? -eq 0 ]] || ((NERRORS++))
|
||||
((NCHECKED++))
|
||||
"$CXX" -xc++ $STD $CXXFLAGS -c -o /dev/null "$H" || : $((NERRORS++))
|
||||
: $((NCHECKED++))
|
||||
done < <(find "$INCLUDEDIR" -name '*.hpp' -type f -print0 2>/dev/null)
|
||||
|
||||
if [[ $NCHECKED -eq 0 ]]; then
|
||||
echo 'No headers found. Is ndn-cxx installed?'
|
||||
echo "No headers found. Is $PROJ installed?"
|
||||
exit 1
|
||||
else
|
||||
echo "$NCHECKED headers checked."
|
||||
|
||||
+24
-16
@@ -1,28 +1,36 @@
|
||||
# CONTINUOUS INTEGRATION SCRIPTS
|
||||
# Continuous Integration Scripts
|
||||
|
||||
## Environment Variables Used in Build Scripts
|
||||
## Environment Variables
|
||||
|
||||
- `NODE_LABELS`: space-separated list of platform properties. The included values are used by
|
||||
the build scripts to select the proper behavior for different operating systems and versions.
|
||||
- `ID`: lower-case string that identifies the operating system, for example: `ID=ubuntu`,
|
||||
`ID=centos`. See [os-release(5)] for more information. On macOS, where `os-release` is
|
||||
not available, we emulate it by setting `ID=macos`.
|
||||
|
||||
The list should normally contain `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
|
||||
- `ID_LIKE`: space-separated list of operating system identifiers that are closely related
|
||||
to the running OS. See [os-release(5)] for more information. The listed values are used
|
||||
by the CI scripts to select the proper behavior for different platforms and OS flavors.
|
||||
|
||||
Example values:
|
||||
Examples:
|
||||
|
||||
- `[OS_TYPE]`: `Linux`, `OSX`
|
||||
- `[DISTRO_TYPE]`: `Ubuntu`, `CentOS`
|
||||
- `[DISTRO_VERSION]`: `Ubuntu-16.04`, `Ubuntu-18.04`, `CentOS-8`, `OSX-10.14`, `OSX-10.15`
|
||||
- On CentOS, `ID_LIKE="centos rhel fedora linux"`
|
||||
- On Ubuntu, `ID_LIKE="ubuntu debian linux"`
|
||||
|
||||
- `JOB_NAME`: optional variable that defines the type of build job. Depending on the job type,
|
||||
the build scripts can perform different tasks.
|
||||
- `VERSION_ID`: identifies the operating system version, excluding any release code names.
|
||||
See [os-release(5)] for more information. Examples: `VERSION_ID=42`, `VERSION_ID=22.04`.
|
||||
|
||||
Possible values:
|
||||
- `JOB_NAME`: defines the type of the current CI job. Depending on the job type, the CI
|
||||
scripts can perform different tasks.
|
||||
|
||||
Supported values:
|
||||
|
||||
- empty: default build task
|
||||
- `code-coverage`: debug build with tests and code coverage analysis (Ubuntu Linux is assumed)
|
||||
- `code-coverage`: debug build with tests and code coverage analysis
|
||||
- `limited-build`: only a single debug build with tests
|
||||
|
||||
- `CACHE_DIR`: directory containing cached files from previous builds, e.g., a compiled version
|
||||
of ndn-cxx. If not set, `/tmp` is used.
|
||||
- `CACHE_DIR`: directory containing cached files from previous builds, e.g., a compiled
|
||||
version of ndn-cxx. If not set, `/tmp` is used.
|
||||
|
||||
- `WAF_JOBS`: number of parallel build threads used by waf, defaults to 1.
|
||||
- `DISABLE_ASAN`: disable building with AddressSanitizer. This is automatically set for
|
||||
the `code-coverage` job type.
|
||||
|
||||
[os-release(5)]: https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||
@@ -1,39 +0,0 @@
|
||||
has() {
|
||||
local saved_xtrace
|
||||
[[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
|
||||
set +x
|
||||
|
||||
local p=$1
|
||||
shift
|
||||
local i ret=1
|
||||
for i in "$@"; do
|
||||
if [[ "${i}" == "${p}" ]]; then
|
||||
ret=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
set ${saved_xtrace}
|
||||
return ${ret}
|
||||
}
|
||||
export -f has
|
||||
|
||||
sudo_preserve_env() {
|
||||
local saved_xtrace
|
||||
[[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
|
||||
set +x
|
||||
|
||||
local vars=()
|
||||
while [[ $# -gt 0 ]]; do
|
||||
local arg=$1
|
||||
shift
|
||||
case ${arg} in
|
||||
--) break ;;
|
||||
*) vars+=("${arg}=${!arg}") ;;
|
||||
esac
|
||||
done
|
||||
|
||||
set ${saved_xtrace}
|
||||
sudo env "${vars[@]}" "$@"
|
||||
}
|
||||
export -f sudo_preserve_env
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
version: ~> 1.0
|
||||
language: cpp
|
||||
os: linux
|
||||
dist: bionic
|
||||
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
- ppc64le
|
||||
- s390x
|
||||
|
||||
env:
|
||||
- COMPILER=g++-7
|
||||
- COMPILER=g++-9
|
||||
- COMPILER=clang++-6.0
|
||||
- COMPILER=clang++-9
|
||||
|
||||
jobs:
|
||||
include:
|
||||
# Linux
|
||||
- env: COMPILER=g++-5
|
||||
- env: COMPILER=g++-6
|
||||
- env: COMPILER=g++-8
|
||||
- env: COMPILER=clang++-4.0
|
||||
- env: COMPILER=clang++-5.0
|
||||
- env: COMPILER=clang++-7
|
||||
- env: COMPILER=clang++-8
|
||||
- env: COMPILER=clang++-10
|
||||
- env: COMPILER=clang++-11
|
||||
- env: COMPILER=clang++-12
|
||||
|
||||
# macOS
|
||||
- os: osx
|
||||
osx_image: xcode9.4
|
||||
env: # default compiler
|
||||
- os: osx
|
||||
osx_image: xcode10.1
|
||||
env: # default compiler
|
||||
- os: osx
|
||||
osx_image: xcode10.3
|
||||
env: # default compiler
|
||||
- os: osx
|
||||
osx_image: xcode11.3
|
||||
env: # default compiler
|
||||
- os: osx
|
||||
osx_image: xcode11.6
|
||||
env: # default compiler
|
||||
- os: osx
|
||||
osx_image: xcode12
|
||||
env: # default compiler
|
||||
|
||||
allow_failures:
|
||||
- env: COMPILER=g++-5
|
||||
- env: COMPILER=g++-6
|
||||
- env: COMPILER=clang++-4.0
|
||||
- env: COMPILER=clang++-12
|
||||
|
||||
fast_finish: true
|
||||
|
||||
before_install:
|
||||
- |
|
||||
: Adding apt repositories
|
||||
case ${COMPILER} in
|
||||
g++-9)
|
||||
# https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages
|
||||
travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
travis_retry sudo apt-get -qq update
|
||||
;;
|
||||
clang++-1?)
|
||||
# https://apt.llvm.org/
|
||||
LLVM_REPO=${COMPILER/clang++/llvm-toolchain-${TRAVIS_DIST}}
|
||||
travis_retry wget -nv -O - "https://apt.llvm.org/llvm-snapshot.gpg.key" | sudo apt-key add -
|
||||
travis_retry sudo add-apt-repository -y "deb http://apt.llvm.org/${TRAVIS_DIST}/ ${LLVM_REPO%-12} main"
|
||||
travis_retry sudo apt-get -qq update
|
||||
;;
|
||||
esac
|
||||
|
||||
install:
|
||||
- |
|
||||
: Installing C++ compiler
|
||||
if [[ -n ${COMPILER} ]]; then
|
||||
travis_retry sudo apt-get -qy install ${COMPILER/clang++/clang}
|
||||
fi
|
||||
|
||||
before_script:
|
||||
- |
|
||||
: Setting environment variables
|
||||
if [[ -n ${COMPILER} ]]; then
|
||||
export CXX=${COMPILER}
|
||||
fi
|
||||
case ${TRAVIS_OS_NAME} in
|
||||
linux) export NODE_LABELS="Linux Ubuntu Ubuntu-18.04" ;;
|
||||
osx) export NODE_LABELS="OSX OSX-$(sw_vers -productVersion | cut -d . -f -2)" ;;
|
||||
esac
|
||||
export JOB_NAME=limited-build
|
||||
export WAF_JOBS=2
|
||||
- |
|
||||
: Enabling workarounds
|
||||
case "${TRAVIS_CPU_ARCH},${COMPILER}" in
|
||||
arm64,g++*)
|
||||
# Avoid exceeding the per-job time limit
|
||||
export DISABLE_HEADERS_CHECK=yes
|
||||
;;
|
||||
ppc64le,g++-7)
|
||||
# AddressSanitizer does not seem to be working
|
||||
export DISABLE_ASAN=yes
|
||||
;;
|
||||
*,clang++-8)
|
||||
# https://bugs.llvm.org/show_bug.cgi?id=40808
|
||||
export DISABLE_ASAN=yes
|
||||
;;
|
||||
esac
|
||||
- ${CXX:-c++} --version
|
||||
|
||||
script:
|
||||
- ./.jenkins
|
||||
+2
-2
@@ -54,8 +54,8 @@ from waflib import Utils, Logs, Errors
|
||||
from waflib.Configure import conf
|
||||
from waflib.TaskGen import feature, after_method
|
||||
|
||||
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
|
||||
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
|
||||
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/homebrew/lib', '/opt/local/lib', '/sw/lib', '/lib']
|
||||
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/homebrew/include', '/opt/local/include', '/sw/include']
|
||||
|
||||
BOOST_VERSION_FILE = 'boost/version.hpp'
|
||||
BOOST_VERSION_CODE = '''
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
from waflib.Configure import conf
|
||||
|
||||
STD_TO_STRING = '''
|
||||
#include <string>
|
||||
int
|
||||
main()
|
||||
{
|
||||
std::string s = std::to_string(0);
|
||||
s = std::to_string(0l);
|
||||
s = std::to_string(0ll);
|
||||
s = std::to_string(0u);
|
||||
s = std::to_string(0ul);
|
||||
s = std::to_string(0ull);
|
||||
s = std::to_string(0.0f);
|
||||
s = std::to_string(0.0);
|
||||
s = std::to_string(0.0l);
|
||||
s.clear();
|
||||
}
|
||||
'''
|
||||
|
||||
@conf
|
||||
def check_std_to_string(self):
|
||||
if self.check_cxx(msg='Checking for std::to_string',
|
||||
fragment=STD_TO_STRING, mandatory=False):
|
||||
self.define('HAVE_STD_TO_STRING', 1)
|
||||
|
||||
def configure(conf):
|
||||
conf.check_std_to_string()
|
||||
@@ -0,0 +1,25 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
from waflib import Utils
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--build', default=Utils.unversioned_sys_platform(),
|
||||
help='Build platform that is doing the actual compilation (e.g., darwin)')
|
||||
opt.add_option('--host', default=Utils.unversioned_sys_platform(),
|
||||
help='Host platform on which the compiled binary will run (e.g., android)')
|
||||
# opt.add_option('--target', default=Utils.unversioned_sys_platform(),
|
||||
# help='Target platform on which the compiled binary's output will run')
|
||||
|
||||
def configure(conf):
|
||||
conf.env.BUILD = conf.options.build
|
||||
conf.env.HOST = conf.options.host
|
||||
# conf.env.TARGET = conf.options.target
|
||||
|
||||
conf.start_msg('Build platform')
|
||||
conf.end_msg(conf.env.BUILD)
|
||||
|
||||
conf.start_msg('Host platform')
|
||||
conf.end_msg(conf.env.HOST)
|
||||
|
||||
# conf.start_msg('Target platform')
|
||||
# conf.end_msg(conf.env.TARGET)
|
||||
@@ -3,10 +3,12 @@
|
||||
import platform
|
||||
from waflib import Configure, Logs, Utils
|
||||
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--debug', '--with-debug', action='store_true', default=False,
|
||||
help='Compile in debugging mode with minimal optimizations (-Og)')
|
||||
|
||||
|
||||
def configure(conf):
|
||||
conf.start_msg('Checking C++ compiler version')
|
||||
|
||||
@@ -16,23 +18,27 @@ def configure(conf):
|
||||
errmsg = ''
|
||||
warnmsg = ''
|
||||
if cxx == 'gcc':
|
||||
if ccver < (5, 3, 0):
|
||||
if ccver < (7, 4, 0):
|
||||
errmsg = ('The version of gcc you are using is too old.\n'
|
||||
'The minimum supported gcc version is 7.4.0.')
|
||||
elif ccver < (7, 4, 0):
|
||||
warnmsg = ('Using a version of gcc older than 7.4.0 is not '
|
||||
'The minimum supported gcc version is 9.3.')
|
||||
elif ccver < (9, 3, 0):
|
||||
warnmsg = ('Using a version of gcc older than 9.3 is not '
|
||||
'officially supported and may result in build failures.')
|
||||
conf.flags = GccFlags()
|
||||
elif cxx == 'clang':
|
||||
if Utils.unversioned_sys_platform() == 'darwin' and ccver < (9, 0, 0):
|
||||
errmsg = ('The version of Xcode you are using is too old.\n'
|
||||
'The minimum supported Xcode version is 9.0.')
|
||||
elif ccver < (4, 0, 0):
|
||||
if Utils.unversioned_sys_platform() == 'darwin':
|
||||
if ccver < (10, 0, 0):
|
||||
errmsg = ('The version of Xcode you are using is too old.\n'
|
||||
'The minimum supported Xcode version is 12.4.')
|
||||
elif ccver < (12, 0, 0):
|
||||
warnmsg = ('Using a version of Xcode older than 12.4 is not '
|
||||
'officially supported and may result in build failures.')
|
||||
elif ccver < (7, 0, 0):
|
||||
errmsg = ('The version of clang you are using is too old.\n'
|
||||
'The minimum supported clang version is 4.0.')
|
||||
'The minimum supported clang version is 7.0.')
|
||||
conf.flags = ClangFlags()
|
||||
else:
|
||||
warnmsg = '%s compiler is unsupported' % cxx
|
||||
warnmsg = f'{cxx} compiler is unsupported'
|
||||
conf.flags = CompilerFlags()
|
||||
|
||||
if errmsg:
|
||||
@@ -44,7 +50,7 @@ def configure(conf):
|
||||
else:
|
||||
conf.end_msg(ccverstr)
|
||||
|
||||
conf.areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
|
||||
conf.areCustomCxxflagsPresent = len(conf.env.CXXFLAGS) > 0
|
||||
|
||||
# General flags are always applied (e.g., selecting C++ language standard)
|
||||
generalFlags = conf.flags.getGeneralFlags(conf)
|
||||
@@ -52,6 +58,7 @@ def configure(conf):
|
||||
conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
|
||||
conf.env.DEFINES += generalFlags['DEFINES']
|
||||
|
||||
|
||||
@Configure.conf
|
||||
def check_compiler_flags(conf):
|
||||
# Debug or optimized CXXFLAGS and LINKFLAGS are applied only if the
|
||||
@@ -74,10 +81,11 @@ def check_compiler_flags(conf):
|
||||
|
||||
conf.env.DEFINES += extraFlags['DEFINES']
|
||||
|
||||
|
||||
@Configure.conf
|
||||
def add_supported_cxxflags(self, cxxflags):
|
||||
"""
|
||||
Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
|
||||
Check which cxxflags are supported by the active compiler and add them to env.CXXFLAGS variable.
|
||||
"""
|
||||
if len(cxxflags) == 0:
|
||||
return
|
||||
@@ -93,10 +101,11 @@ def add_supported_cxxflags(self, cxxflags):
|
||||
self.end_msg(' '.join(supportedFlags))
|
||||
self.env.prepend_value('CXXFLAGS', supportedFlags)
|
||||
|
||||
|
||||
@Configure.conf
|
||||
def add_supported_linkflags(self, linkflags):
|
||||
"""
|
||||
Check which linkflags are supported by compiler and add them to env.LINKFLAGS variable
|
||||
Check which linkflags are supported by the active compiler and add them to env.LINKFLAGS variable.
|
||||
"""
|
||||
if len(linkflags) == 0:
|
||||
return
|
||||
@@ -113,13 +122,17 @@ def add_supported_linkflags(self, linkflags):
|
||||
self.env.prepend_value('LINKFLAGS', supportedFlags)
|
||||
|
||||
|
||||
class CompilerFlags(object):
|
||||
class CompilerFlags:
|
||||
def getCompilerVersion(self, conf):
|
||||
return tuple(int(i) for i in conf.env.CC_VERSION)
|
||||
|
||||
def getGeneralFlags(self, conf):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
|
||||
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
|
||||
return {
|
||||
'CXXFLAGS': [],
|
||||
'LINKFLAGS': [],
|
||||
'DEFINES': ['BOOST_ASIO_NO_DEPRECATED', 'BOOST_FILESYSTEM_NO_DEPRECATED'],
|
||||
}
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
|
||||
@@ -129,99 +142,100 @@ class CompilerFlags(object):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in optimized mode"""
|
||||
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['NDEBUG']}
|
||||
|
||||
class GccBasicFlags(CompilerFlags):
|
||||
|
||||
class GccClangCommonFlags(CompilerFlags):
|
||||
"""
|
||||
This class defines basic flags that work for both gcc and clang compilers
|
||||
This class defines common flags that work for both gcc and clang compilers.
|
||||
"""
|
||||
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getGeneralFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-std=c++14']
|
||||
if Utils.unversioned_sys_platform() == 'linux':
|
||||
flags['LINKFLAGS'] += ['-fuse-ld=gold']
|
||||
elif Utils.unversioned_sys_platform() == 'freebsd':
|
||||
flags = super().getGeneralFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-std=c++17']
|
||||
if Utils.unversioned_sys_platform() != 'darwin':
|
||||
flags['LINKFLAGS'] += ['-fuse-ld=lld']
|
||||
return flags
|
||||
|
||||
__cxxFlags = [
|
||||
'-fdiagnostics-color',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wpedantic',
|
||||
'-Wenum-conversion',
|
||||
'-Wextra-semi',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
__linkFlags = ['-Wl,-O1']
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-Og',
|
||||
'-g3',
|
||||
'-pedantic',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Werror',
|
||||
'-Wcatch-value=2',
|
||||
'-Wextra-semi',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-Wno-error=deprecated-declarations', # Bug #3795
|
||||
'-Wno-error=maybe-uninitialized', # Bug #1615
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
flags['LINKFLAGS'] += ['-Wl,-O1']
|
||||
flags = super().getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-Og', '-g'] + self.__cxxFlags + [
|
||||
'-Werror',
|
||||
'-Wno-error=deprecated-declarations', # Bug #3795
|
||||
'-Wno-error=maybe-uninitialized', # Bug #1615
|
||||
]
|
||||
flags['LINKFLAGS'] += self.__linkFlags
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-O2',
|
||||
'-g',
|
||||
'-pedantic',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wcatch-value=2',
|
||||
'-Wextra-semi',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
flags['LINKFLAGS'] += ['-Wl,-O1']
|
||||
flags = super().getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-O2', '-g1'] + self.__cxxFlags
|
||||
flags['LINKFLAGS'] += self.__linkFlags
|
||||
return flags
|
||||
|
||||
class GccFlags(GccBasicFlags):
|
||||
|
||||
class GccFlags(GccClangCommonFlags):
|
||||
__cxxFlags = [
|
||||
'-Wcatch-value=2',
|
||||
'-Wcomma-subscript', # enabled by default in C++20
|
||||
'-Wduplicated-branches',
|
||||
'-Wduplicated-cond',
|
||||
'-Wlogical-op',
|
||||
'-Wredundant-tags',
|
||||
'-Wvolatile', # enabled by default in C++20
|
||||
]
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(GccFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color',
|
||||
'-Wredundant-tags',
|
||||
]
|
||||
if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
|
||||
flags = super().getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
if platform.machine() == 'armv7l':
|
||||
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(GccFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color',
|
||||
'-Wredundant-tags',
|
||||
]
|
||||
if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
|
||||
flags = super().getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
if platform.machine() == 'armv7l':
|
||||
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
|
||||
return flags
|
||||
|
||||
class ClangFlags(GccBasicFlags):
|
||||
|
||||
class ClangFlags(GccClangCommonFlags):
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getGeneralFlags(conf)
|
||||
flags = super().getGeneralFlags(conf)
|
||||
if Utils.unversioned_sys_platform() == 'darwin':
|
||||
# Bug #4296
|
||||
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
|
||||
['-isystem', '/opt/local/include']] # for MacPorts
|
||||
brewdir = '/opt/homebrew' if platform.machine() == 'arm64' else '/usr/local'
|
||||
flags['CXXFLAGS'] += [
|
||||
['-isystem', f'{brewdir}/include'], # for Homebrew
|
||||
['-isystem', '/opt/local/include'], # for MacPorts
|
||||
]
|
||||
elif Utils.unversioned_sys_platform() == 'freebsd':
|
||||
# Bug #4790
|
||||
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']]
|
||||
return flags
|
||||
|
||||
__cxxFlags = [
|
||||
'-Wundefined-func-template',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
|
||||
'-Wundefined-func-template',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
if self.getCompilerVersion(conf) < (6, 0, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
|
||||
flags = super().getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
|
||||
'-Wundefined-func-template',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
if self.getCompilerVersion(conf) < (6, 0, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
|
||||
flags = super().getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
return flags
|
||||
+55
-49
@@ -1,10 +1,8 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
# Yingdi Yu (UCLA) 2016
|
||||
|
||||
'''
|
||||
|
||||
When using this tool, the wscript will look like:
|
||||
"""
|
||||
When using this tool, the wscript should look like:
|
||||
|
||||
def options(opt):
|
||||
opt.load('openssl')
|
||||
@@ -15,15 +13,17 @@ When using this tool, the wscript will look like:
|
||||
|
||||
def build(bld):
|
||||
bld(source='main.cpp', target='app', use='OPENSSL')
|
||||
|
||||
'''
|
||||
"""
|
||||
|
||||
import re
|
||||
from waflib import Utils
|
||||
from waflib.Configure import conf
|
||||
|
||||
OPENSSL_DIR_OSX = ['/usr/local', '/opt/local', '/usr/local/opt/openssl']
|
||||
OPENSSL_DIR = ['/usr', '/usr/local', '/opt/local', '/sw']
|
||||
OPENSSL_DIR_MACOS = ['/usr/local',
|
||||
'/opt/homebrew/opt/openssl', # Homebrew on arm64
|
||||
'/usr/local/opt/openssl', # Homebrew on x86_64
|
||||
'/opt/local'] # MacPorts
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--with-openssl', type='string', default=None, dest='openssl_dir',
|
||||
@@ -37,55 +37,62 @@ def __openssl_get_version_file(self, dir):
|
||||
return None
|
||||
|
||||
@conf
|
||||
def __openssl_find_root_and_version_file(self, *k, **kw):
|
||||
root = k and k[0] or kw.get('path', self.options.openssl_dir)
|
||||
|
||||
file = self.__openssl_get_version_file(root)
|
||||
if root and file:
|
||||
def __openssl_find_root_and_version_file(self, root):
|
||||
if root:
|
||||
file = self.__openssl_get_version_file(root)
|
||||
if not file:
|
||||
self.fatal(f'OpenSSL not found in {root}')
|
||||
return (root, file)
|
||||
|
||||
openssl_dir = []
|
||||
openssl_dirs = OPENSSL_DIR
|
||||
if Utils.unversioned_sys_platform() == 'darwin':
|
||||
openssl_dir = OPENSSL_DIR_OSX
|
||||
else:
|
||||
openssl_dir = OPENSSL_DIR
|
||||
openssl_dirs = OPENSSL_DIR_MACOS
|
||||
|
||||
if not root:
|
||||
for dir in openssl_dir:
|
||||
file = self.__openssl_get_version_file(dir)
|
||||
if file:
|
||||
return (dir, file)
|
||||
for dir in openssl_dirs:
|
||||
file = self.__openssl_get_version_file(dir)
|
||||
if file:
|
||||
return (dir, file)
|
||||
|
||||
if root:
|
||||
self.fatal('OpenSSL not found in %s' % root)
|
||||
else:
|
||||
self.fatal('OpenSSL not found, please provide a --with-openssl=PATH argument (see help)')
|
||||
self.fatal('OpenSSL not found, please provide a --with-openssl=PATH argument (see --help)')
|
||||
|
||||
@conf
|
||||
def __openssl_check_version(self, version_file, atleast_version):
|
||||
min_version = tuple(int(i) for i in atleast_version.split('.'))
|
||||
txt = version_file.read()
|
||||
|
||||
# OpenSSL 3.0.0 and later
|
||||
ver_tuple = (re.search(r'^#\s*define\s+OPENSSL_VERSION_MAJOR\s+(\d+)', txt, re.MULTILINE),
|
||||
re.search(r'^#\s*define\s+OPENSSL_VERSION_MINOR\s+(\d+)', txt, re.MULTILINE),
|
||||
re.search(r'^#\s*define\s+OPENSSL_VERSION_PATCH\s+(\d+)', txt, re.MULTILINE))
|
||||
ver_string = re.search(r'^#\s*define\s+OPENSSL_FULL_VERSION_STR\s+"(.+)"', txt, re.MULTILINE)
|
||||
if all(ver_tuple):
|
||||
version = tuple(int(i[1]) for i in ver_tuple)
|
||||
ver_string = ver_string[1] if ver_string else '.'.join(version)
|
||||
return (version >= min_version, ver_string)
|
||||
|
||||
# OpenSSL 1.1.1 and earlier
|
||||
ver_number = re.search(r'^#\s*define\s+OPENSSL_VERSION_NUMBER\s+(.+)L', txt, re.MULTILINE)
|
||||
ver_string = re.search(r'^#\s*define\s+OPENSSL_VERSION_TEXT\s+"(.+)"', txt, re.MULTILINE)
|
||||
if ver_number and ver_string:
|
||||
version = int(ver_number[1], 16)
|
||||
min_version = (min_version[0] << 28) | (min_version[1] << 20) | (min_version[2] << 12) | 0xf
|
||||
return (version >= min_version, ver_string[1])
|
||||
|
||||
self.fatal(f'Cannot extract version information from {version_file}')
|
||||
|
||||
@conf
|
||||
def check_openssl(self, *k, **kw):
|
||||
self.start_msg('Checking for OpenSSL version')
|
||||
(root, file) = self.__openssl_find_root_and_version_file(*k, **kw)
|
||||
|
||||
try:
|
||||
txt = file.read()
|
||||
re_version = re.compile('^#\\s*define\\s+OPENSSL_VERSION_NUMBER\\s+(.*)L', re.M)
|
||||
version_number = re_version.search(txt)
|
||||
|
||||
re_version_text = re.compile('^#\\s*define\\s+OPENSSL_VERSION_TEXT\\s+(.*)', re.M)
|
||||
version_text = re_version_text.search(txt)
|
||||
|
||||
if version_number and version_text:
|
||||
version = version_number.group(1)
|
||||
self.end_msg(version_text.group(1))
|
||||
else:
|
||||
self.fatal('OpenSSL version file is present, but is not recognizable')
|
||||
except:
|
||||
self.fatal('OpenSSL version file is not found or is not usable')
|
||||
|
||||
path = k and k[0] or kw.get('path', self.options.openssl_dir)
|
||||
root, version_file = self.__openssl_find_root_and_version_file(path)
|
||||
atleast_version = kw.get('atleast_version', 0)
|
||||
if int(version, 16) < atleast_version:
|
||||
self.fatal('The version of OpenSSL is too old\n'
|
||||
'Please upgrade your distribution or manually install a newer version of OpenSSL')
|
||||
ok, version_str = self.__openssl_check_version(version_file, atleast_version)
|
||||
|
||||
self.end_msg(version_str)
|
||||
if not ok:
|
||||
self.fatal(f'The version of OpenSSL is too old; {atleast_version} or later is required.\n'
|
||||
'Please upgrade your distribution or manually install a newer version of OpenSSL.')
|
||||
|
||||
if 'msg' not in kw:
|
||||
kw['msg'] = 'Checking if OpenSSL library works'
|
||||
@@ -94,9 +101,8 @@ def check_openssl(self, *k, **kw):
|
||||
if 'uselib_store' not in kw:
|
||||
kw['uselib_store'] = 'OPENSSL'
|
||||
if 'define_name' not in kw:
|
||||
kw['define_name'] = 'HAVE_%s' % kw['uselib_store']
|
||||
if root:
|
||||
kw['includes'] = '%s/include' % root
|
||||
kw['libpath'] = '%s/lib' % root
|
||||
kw['define_name'] = f"HAVE_{kw['uselib_store']}"
|
||||
kw['includes'] = f'{root}/include'
|
||||
kw['libpath'] = f'{root}/lib'
|
||||
|
||||
self.check_cxx(**kw)
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
# ndn-cxx Authors
|
||||
|
||||
The following lists maintainers, primary developers, and all much-appreciated contributors to ndn-cxx in alphabetic order.
|
||||
The following lists maintainers, primary developers, and all much-appreciated contributors to ndn-cxx in alphabetical order.
|
||||
The specific contributions of individual authors can be obtained from the git history of the [official ndn-cxx repository](https://github.com/named-data/ndn-cxx).
|
||||
If you would like to become a contributor to the official repository, please follow the recommendations in https://github.com/named-data/.github/blob/master/CONTRIBUTING.md.
|
||||
If you would like to become a contributor to the official repository, please follow the recommendations in <https://github.com/named-data/.github/blob/main/CONTRIBUTING.md>.
|
||||
|
||||
* Sepehr Abdous <https://sepehrabdous.github.io>
|
||||
* ***(Maintainer)*** Alexander Afanasyev <https://users.cs.fiu.edu/~afanasyev>
|
||||
@@ -23,7 +23,7 @@ If you would like to become a contributor to the official repository, please fol
|
||||
* Xiaoke Jiang <http://netarchlab.tsinghua.edu.cn/~shock>
|
||||
* Marcin Juszkiewicz <https://marcin.juszkiewicz.com.pl>
|
||||
* Luca Keidel <https://lucakeidel.de>
|
||||
* Spencer Lee <https://wwsw.linkedin.com/in/spenlee>
|
||||
* Spencer Lee <https://www.linkedin.com/in/spenlee>
|
||||
* Vince Lehman <http://vslehman.com>
|
||||
* Yanbiao Li <https://www.linkedin.com/pub/yanbiao-li/24/7a1/4ba>
|
||||
* Teng Liang <https://cs.arizona.edu/~philoliang>
|
||||
@@ -39,7 +39,7 @@ If you would like to become a contributor to the official repository, please fol
|
||||
* Arthi Padmanabhan <https://github.com/arthipadmanabhan>
|
||||
* Ju Pan <https://cs-jupan.com>
|
||||
* João Pereira <http://website.jpereira.co.uk>
|
||||
* Davide Pesavento <https://github.com/Pesa>
|
||||
* ***(Maintainer)*** Davide Pesavento <https://github.com/Pesa>
|
||||
* José Quevedo <http://atnog.av.it.pt/members/jquevedo>
|
||||
* Md Ashiqur Rahman <https://ashiqrahman.com>
|
||||
* Niv Sardi <http://core.evilgiggle.com>
|
||||
|
||||
+11
-19
@@ -6,38 +6,30 @@ ndn-cxx relies on third-party software, licensed under the following licenses:
|
||||
- The Boost libraries are licensed under the
|
||||
[Boost Software License 1.0](https://www.boost.org/users/license.html)
|
||||
|
||||
- any-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/any-lite/blob/master/LICENSE.txt)
|
||||
|
||||
- optional-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/optional-lite/blob/master/LICENSE.txt)
|
||||
- OpenSSL is licensed under the
|
||||
[Apache License 2.0](https://www.openssl.org/source/license.html)
|
||||
|
||||
- scope-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/scope-lite/blob/master/LICENSE.txt)
|
||||
|
||||
- variant-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/variant-lite/blob/master/LICENSE.txt)
|
||||
- span-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/span-lite/blob/master/LICENSE.txt)
|
||||
|
||||
- SQLite is in the [public domain](https://www.sqlite.org/copyright.html)
|
||||
|
||||
- The waf build system is licensed under the terms of the
|
||||
[BSD license](https://github.com/named-data/ndn-cxx/blob/master/waf)
|
||||
|
||||
The ndn-cxx library also relies on other third-party software with a GPL-incompatible
|
||||
free software license. The following libraries fall into the category of "System
|
||||
Libraries" under the GPL license definitions and are used in accordance with the GPL
|
||||
license exception for "System Libraries":
|
||||
|
||||
The ndn-cxx library also relies on several other third-party libraries with non-GPL
|
||||
compatible license. These library fall into category of "System Libraries" under GPL
|
||||
license definitions and are used in accordance with GPL license exception for "System
|
||||
Libraries":
|
||||
|
||||
- OpenSSL is licensed under an
|
||||
[Apache-style license](https://www.openssl.org/source/license.html)
|
||||
|
||||
- (macOS platform only) The macOS Security Framework is licensed under the
|
||||
[Apple Public Source License](https://opensource.apple.com/apsl)
|
||||
|
||||
- *(macOS platform only)* The macOS Security Framework is licensed under the
|
||||
[Apple Public Source License 2.0](https://opensource.apple.com/apsl)
|
||||
|
||||
The LGPL and GPL licenses are provided below in this file. For more information
|
||||
about these licenses, see https://www.gnu.org/licenses/
|
||||
about these licenses, see <https://www.gnu.org/licenses/>
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
FROM gcc:12-bookworm
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
dpkg-dev \
|
||||
libboost-atomic-dev \
|
||||
libboost-chrono-dev \
|
||||
libboost-date-time-dev \
|
||||
libboost-filesystem-dev \
|
||||
libboost-iostreams-dev \
|
||||
libboost-log-dev \
|
||||
libboost-program-options-dev \
|
||||
libboost-regex-dev \
|
||||
libboost-stacktrace-dev \
|
||||
libboost-system-dev \
|
||||
pkg-config \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY . /ndn-cxx
|
||||
|
||||
RUN cd /ndn-cxx \
|
||||
&& ./waf configure --without-pch --prefix=/usr --sysconfdir=/etc --localstatedir=/var --disable-static --enable-shared \
|
||||
&& ./waf \
|
||||
&& ./waf install \
|
||||
&& cd \
|
||||
&& rm -rf /ndn-cxx
|
||||
+8
-13
@@ -1,20 +1,20 @@
|
||||
Notes for ndn-cxx developers
|
||||
============================
|
||||
|
||||
If you are new to the NDN community of software generally, read the
|
||||
[Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md).
|
||||
If you are new to the NDN software community, please read our
|
||||
[Contributor's Guide](https://github.com/named-data/.github/blob/main/CONTRIBUTING.md).
|
||||
|
||||
Code style
|
||||
----------
|
||||
|
||||
ndn-cxx code is subject to [ndn-cxx code style](https://named-data.net/doc/ndn-cxx/current/code-style.html).
|
||||
ndn-cxx code is subject to [ndn-cxx code style](https://docs.named-data.net/ndn-cxx/current/code-style.html).
|
||||
|
||||
Licensing
|
||||
---------
|
||||
|
||||
Contributions to the library must be licensed under the LGPL v3 or compatible license. If
|
||||
you are choosing LGPL v3, please use the following license boilerplate in all `.hpp` and
|
||||
`.cpp` files:
|
||||
Contributions to ndn-cxx must be licensed under the LGPL v3 or a compatible license.
|
||||
If you choose the LGPL v3, please use the following license boilerplate in all `.hpp`
|
||||
and `.cpp` files:
|
||||
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
@@ -35,11 +35,6 @@ you are choosing LGPL v3, please use the following license boilerplate in all `.
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
////// [optional part] //////
|
||||
*
|
||||
* @author Author's Name <email@domain-or-homepage://url>
|
||||
* @author Other Author's Name <another.email@domain-or-homepage://url>
|
||||
////// [end of optional part] //////
|
||||
*/
|
||||
|
||||
If you are affiliated to an NSF-supported NDN project institution, please use the [NDN Team License
|
||||
@@ -62,7 +57,7 @@ The simplest way to run the tests is to launch the compiled binary without any p
|
||||
|
||||
./build/unit-tests
|
||||
|
||||
The [Boost.Test framework](https://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/index.html)
|
||||
The [Boost.Test framework](https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/index.html)
|
||||
is very flexible and allows a number of run-time customization of what tests should be run.
|
||||
For example, it is possible to choose to run only a specific test suite, only a specific
|
||||
test case within a suite, or specific test cases within specific test suites:
|
||||
@@ -95,7 +90,7 @@ or `-p` to show a progress bar:
|
||||
|
||||
There are many more command line options available, information about which can be obtained
|
||||
either from the command line using the `--help` switch, or online on the
|
||||
[Boost.Test website](https://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/index.html).
|
||||
[Boost.Test website](https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/boost_test/runtime_config.html).
|
||||
|
||||
**Warning:** If you have customized parameters for NDN platform using `client.conf` in
|
||||
`/etc/ndn` or `/usr/local/etc/ndn` (or other `@SYSCONFDIR@/etc` if it was configured to custom
|
||||
|
||||
@@ -1,42 +1,51 @@
|
||||
<div align="center">
|
||||
|
||||
[<img alt height="65" src="docs/named_data_theme/static/ndn-logo.svg"/>](https://named-data.net/)
|
||||
|
||||
# ndn-cxx: NDN C++ library with eXperimental eXtensions
|
||||
|
||||

|
||||
[](https://travis-ci.org/named-data/ndn-cxx)
|
||||

|
||||
</div>
|
||||
|
||||
**ndn-cxx** is a C++14 library implementing Named Data Networking (NDN) primitives
|
||||
[](https://github.com/named-data/ndn-cxx/actions/workflows/ci.yml)
|
||||
[](https://github.com/named-data/ndn-cxx/actions/workflows/docs.yml)
|
||||

|
||||

|
||||
|
||||
**ndn-cxx** is a C++17 library implementing Named Data Networking (NDN) primitives
|
||||
that can be used to write various NDN applications. The library is currently being
|
||||
used by the following projects:
|
||||
|
||||
* [NFD - NDN Forwarding Daemon](https://github.com/named-data/NFD)
|
||||
* [NLSR - Named-data Link-State Routing protocol](https://github.com/named-data/NLSR)
|
||||
* [ndn-tools - Essential NDN command-line tools](https://github.com/named-data/ndn-tools)
|
||||
* [repo-ng - Next generation NDN repository](https://github.com/named-data/repo-ng)
|
||||
* [ChronoSync - Sync library for multi-user real-time applications](https://github.com/named-data/ChronoSync)
|
||||
* [PSync - Partial and full synchronization library](https://github.com/named-data/PSync)
|
||||
* [ndn-traffic-generator - Traffic generator for NDN](https://github.com/named-data/ndn-traffic-generator)
|
||||
* [NAC - Name-based Access Control](https://github.com/named-data/name-based-access-control)
|
||||
* [NDNS - Domain Name Service for NDN](https://github.com/named-data/ndns)
|
||||
* [**NFD** - NDN Forwarding Daemon](https://github.com/named-data/NFD)
|
||||
* [**NLSR** - Named-data Link-State Routing protocol](https://github.com/named-data/NLSR)
|
||||
* [**ndn-tools** - Essential NDN command-line tools](https://github.com/named-data/ndn-tools)
|
||||
* [**ndn-svs** - State Vector Sync library](https://github.com/named-data/ndn-svs)
|
||||
* [**PSync** - Partial and full Sync library](https://github.com/named-data/PSync)
|
||||
* [**ChronoSync** - Sync library for distributed real-time applications *(deprecated)*](https://github.com/named-data/ChronoSync)
|
||||
* [**NAC** - Name-based Access Control library](https://github.com/named-data/name-based-access-control)
|
||||
* [**NDNCERT** - NDN certificate management protocol](https://github.com/named-data/ndncert)
|
||||
* [**repo-ng** - NDN repository implementation in C++ *(deprecated)*](https://github.com/named-data/repo-ng)
|
||||
* [**ndn-traffic-generator** - Simple NDN traffic generator](https://github.com/named-data/ndn-traffic-generator)
|
||||
|
||||
## Documentation
|
||||
|
||||
See [`docs/INSTALL.rst`](docs/INSTALL.rst) for compilation and installation instructions.
|
||||
|
||||
Extensive documentation is available on the library's [homepage](https://named-data.net/doc/ndn-cxx/).
|
||||
Extensive documentation is available on the library's [homepage](https://docs.named-data.net/ndn-cxx/).
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
Please submit any bugs or feature requests to the
|
||||
Please submit any bug reports or feature requests to the
|
||||
[ndn-cxx issue tracker](https://redmine.named-data.net/projects/ndn-cxx/issues).
|
||||
|
||||
## Contributing
|
||||
|
||||
We greatly appreciate contributions to the ndn-cxx code base.
|
||||
If you are new to the NDN software community, please read the
|
||||
[Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md)
|
||||
to get started.
|
||||
Contributions to ndn-cxx are greatly appreciated and can be made through our
|
||||
[Gerrit code review site](https://gerrit.named-data.net/).
|
||||
If you are new to the NDN software community, please read our
|
||||
[Contributor's Guide](https://github.com/named-data/.github/blob/main/CONTRIBUTING.md)
|
||||
and [`README-dev.md`](README-dev.md) to get started.
|
||||
|
||||
## License
|
||||
|
||||
ndn-cxx is an open source project licensed under the LGPL version 3.
|
||||
See [`COPYING.md`](COPYING.md) for more information.
|
||||
ndn-cxx is free software distributed under the GNU Lesser General Public License version 3.
|
||||
See [`COPYING.md`](COPYING.md) for details.
|
||||
@@ -1 +0,0 @@
|
||||
docs/release-notes-latest.rst
|
||||
+55
-45
@@ -7,21 +7,22 @@ Supported platforms
|
||||
ndn-cxx is built against a continuous integration system and has been tested on the
|
||||
following platforms:
|
||||
|
||||
- Ubuntu 18.04 (amd64, armhf, i386)
|
||||
- Ubuntu 20.04 (amd64)
|
||||
- macOS 10.13
|
||||
- macOS 10.14
|
||||
- macOS 10.15
|
||||
- CentOS 8
|
||||
- Ubuntu 20.04 (focal)
|
||||
- Ubuntu 22.04 (jammy)
|
||||
- Debian 11 (bullseye)
|
||||
- Debian 12 (bookworm)
|
||||
- CentOS Stream 9
|
||||
- macOS 11 / 12 / 13 / 14
|
||||
|
||||
ndn-cxx is known to work on the following platforms, although they are not officially
|
||||
ndn-cxx should also work on the following platforms, although they are not officially
|
||||
supported:
|
||||
|
||||
- Debian 10 (Buster)
|
||||
- Fedora >= 29
|
||||
- Gentoo Linux
|
||||
- Raspbian >= 2019-06-20 (Buster)
|
||||
- FreeBSD >= 11.3
|
||||
- Any other recent version of Ubuntu not listed above
|
||||
- Fedora >= 33
|
||||
- Alpine >= 3.12
|
||||
- Any version of Raspberry Pi OS based on Debian 11 (bullseye) or later
|
||||
- macOS 10.15
|
||||
- FreeBSD >= 12.2
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
@@ -29,22 +30,22 @@ Prerequisites
|
||||
Required
|
||||
~~~~~~~~
|
||||
|
||||
- GCC >= 7.4 or clang >= 4.0 (on Linux and FreeBSD)
|
||||
- Xcode >= 9.0 (on macOS)
|
||||
- Python >= 3.6
|
||||
- pkg-config
|
||||
- Boost >= 1.65.1
|
||||
- OpenSSL >= 1.0.2
|
||||
- SQLite 3.x
|
||||
- GCC >= 9.3 or clang >= 7.0 (if you are on Linux or FreeBSD)
|
||||
- Xcode >= 12.4 or corresponding version of Command Line Tools (if you are on macOS)
|
||||
- Python >= 3.8
|
||||
- pkg-config
|
||||
- Boost >= 1.71.0
|
||||
- OpenSSL >= 1.1.1
|
||||
- SQLite 3.x
|
||||
|
||||
To build ndn-cxx from source, one must first install a C++ compiler and all necessary
|
||||
development tools and libraries:
|
||||
|
||||
- On **Ubuntu**
|
||||
- On **Debian** and **Ubuntu**
|
||||
|
||||
In a terminal, enter::
|
||||
|
||||
sudo apt install g++ pkg-config python3-minimal libboost-all-dev libssl-dev libsqlite3-dev
|
||||
sudo apt install build-essential pkg-config python3-minimal libboost-all-dev libssl-dev libsqlite3-dev
|
||||
|
||||
- On **CentOS** and **Fedora**
|
||||
|
||||
@@ -57,7 +58,9 @@ development tools and libraries:
|
||||
* Install either Xcode (from the App Store) or the Command Line Tools
|
||||
(with ``xcode-select --install``)
|
||||
|
||||
* If using Homebrew (recommended), enter the following in a terminal::
|
||||
* If using Homebrew (recommended), enter the following in a terminal:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
brew install boost openssl pkg-config
|
||||
|
||||
@@ -75,28 +78,35 @@ development tools and libraries:
|
||||
Optional
|
||||
~~~~~~~~
|
||||
|
||||
To build tutorials, manpages, and API documentation the following additional dependencies
|
||||
To build tutorials, man pages, and API documentation the following additional dependencies
|
||||
need to be installed:
|
||||
|
||||
- doxygen
|
||||
- graphviz
|
||||
- sphinx >= 1.3
|
||||
- sphinxcontrib-doxylink
|
||||
- doxygen
|
||||
- graphviz
|
||||
- sphinx >= 4.0
|
||||
- sphinxcontrib-doxylink
|
||||
|
||||
The following lists the steps to install these prerequisites on various common platforms.
|
||||
|
||||
- On **Ubuntu**:
|
||||
.. note::
|
||||
On Linux, you may need to add ``$HOME/.local/bin`` to the ``PATH`` environment variable
|
||||
for your user, for example:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
|
||||
|
||||
- On **Debian** and **Ubuntu**:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
sudo apt install doxygen graphviz python3-pip
|
||||
sudo pip3 install sphinx sphinxcontrib-doxylink
|
||||
pip3 install --user sphinx sphinxcontrib-doxylink
|
||||
|
||||
- On **CentOS** and **Fedora**:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
sudo dnf config-manager --enable PowerTools # on CentOS only
|
||||
sudo dnf install doxygen graphviz python3-pip
|
||||
pip3 install --user sphinx sphinxcontrib-doxylink
|
||||
|
||||
@@ -105,13 +115,13 @@ The following lists the steps to install these prerequisites on various common p
|
||||
.. code-block:: sh
|
||||
|
||||
brew install doxygen graphviz
|
||||
sudo pip install sphinx sphinxcontrib-doxylink
|
||||
sudo pip3 install sphinx sphinxcontrib-doxylink
|
||||
|
||||
- On **FreeBSD**:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
sudo pkg install doxygen graphviz py37-sphinx
|
||||
sudo pkg install doxygen graphviz py39-sphinx
|
||||
|
||||
Build
|
||||
-----
|
||||
@@ -124,7 +134,7 @@ To build in a terminal, change directory to the ndn-cxx root, then enter:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
./waf configure # on CentOS, add --without-pch
|
||||
./waf configure
|
||||
./waf
|
||||
sudo ./waf install
|
||||
|
||||
@@ -151,12 +161,12 @@ been installed:
|
||||
sudo ldconfig
|
||||
|
||||
.. note::
|
||||
When the library is installed in a non-standard path (in general: not in ``/usr/lib``
|
||||
or ``/usr/local/lib``; on some Linux distros including Fedora: not in ``/usr/lib``),
|
||||
additional actions may be necessary.
|
||||
When the library is installed in a non-default location (in general: not in ``/usr/lib``
|
||||
or ``/usr/local/lib``; on some Linux distros like Fedora and its derivatives, including
|
||||
CentOS: not in ``/usr/lib``), the following additional actions may be necessary.
|
||||
|
||||
The installation path should be added to ``/etc/ld.so.conf`` (or in
|
||||
``/etc/ld.so.conf.d``) **before** running ``sudo ldconfig``. For example:
|
||||
The library installation path should be added to ``/etc/ld.so.conf`` or in
|
||||
``/etc/ld.so.conf.d/*.conf`` **before** running ``ldconfig``. For example:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
@@ -180,7 +190,7 @@ The ``./waf install`` command installs the following files:
|
||||
package is installed and ``PKG_CONFIG_PATH`` is configured properly (or if
|
||||
``<LIBPATH>/pkgconfig`` is a default search path), the command ``pkg-config --cflags
|
||||
--libs libndn-cxx`` will return all necessary compile and link flags for the library.
|
||||
- ``<BINPATH>/ndnsec``: tool to manage NDN keys and certificates.
|
||||
- ``<BINPATH>/ndnsec``: command-line tool to manage NDN keys and certificates.
|
||||
- ``<BINPATH>/ndnsec-*``: convenience aliases for ``ndnsec`` tools.
|
||||
|
||||
If configured with tests (``./waf configure --with-tests``), the above commands
|
||||
@@ -202,7 +212,7 @@ them, pass ``--with-examples`` during the configuration step:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
./waf configure --with-examples # on CentOS, add --without-pch
|
||||
./waf configure --with-examples
|
||||
./waf
|
||||
sudo ./waf install
|
||||
sudo ldconfig # on Linux only
|
||||
@@ -275,9 +285,9 @@ Tutorials and API documentation can be built using the following commands:
|
||||
# Only API docs in build/docs/doxygen
|
||||
./waf doxygen
|
||||
|
||||
If ``sphinx-build`` is detected during ``./waf configure``, manpages will automatically
|
||||
If ``sphinx-build`` is detected during ``./waf configure``, man pages will automatically
|
||||
be built and installed during the normal build process (i.e., during ``./waf`` and
|
||||
``./waf install``). By default, manpages will be installed into ``${PREFIX}/share/man``
|
||||
``./waf install``). By default, man pages will be installed into ``${PREFIX}/share/man``
|
||||
(the default value for ``PREFIX`` is ``/usr/local``). This location can be changed
|
||||
during the ``./waf configure`` stage using the ``--prefix``, ``--datarootdir``, or
|
||||
``--mandir`` options.
|
||||
@@ -293,7 +303,7 @@ The following is the suggested build procedure for development builds:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
./waf configure --debug --with-tests # on CentOS, add --without-pch
|
||||
./waf configure --debug --with-tests
|
||||
./waf
|
||||
sudo ./waf install
|
||||
sudo ldconfig # on Linux only
|
||||
@@ -304,5 +314,5 @@ will be treated as errors. This default behavior can be overridden by setting th
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
CXXFLAGS="-O1 -g3" ./waf configure --debug --with-tests
|
||||
...
|
||||
CXXFLAGS="-O1 -g3 -Wall" ./waf configure --debug --with-tests
|
||||
./waf
|
||||
@@ -1,4 +0,0 @@
|
||||
Release Notes
|
||||
+++++++++++++
|
||||
|
||||
.. include:: release-notes-latest.rst
|
||||
+100
-95
@@ -3,11 +3,11 @@ ndn-cxx Code Style and Coding Guidelines
|
||||
|
||||
Based on
|
||||
|
||||
* "C++ Programming Style Guidelines" by Geotechnical Software Services, Copyright © 1996 – 2011.
|
||||
The original document is available at `<http://geosoft.no/development/cppstyle.html>`_
|
||||
* "C++ Programming Style Guidelines" by Geotechnical Software Services, Copyright © 1996-2011.
|
||||
The original document is available at `<http://geosoft.no/development/cppstyle.html>`__
|
||||
|
||||
* NDN Platform "C++, C, C#, Java and JavaScript Code Guidelines".
|
||||
The original document available at `<https://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/>`_
|
||||
* NDN Platform "C++, C, C#, Java and JavaScript Code Guidelines".
|
||||
The original document is available at `<https://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/>`__
|
||||
|
||||
1. Code layout
|
||||
--------------
|
||||
@@ -31,14 +31,14 @@ extended it to C++.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
a = (b + c) * d; // NOT: a=(b+c)*d
|
||||
a = (b + c) * d; // NOT: a=(b+c)*d
|
||||
|
||||
while (true) { // NOT: while(true)
|
||||
while (true) { // NOT: while(true)
|
||||
...
|
||||
|
||||
doSomething(a, b, c, d); // NOT: doSomething(a,b,c,d);
|
||||
doSomething(a, b, c, d); // NOT: doSomething(a,b,c,d);
|
||||
|
||||
for (i = 0; i < 10; i++) { // NOT: for(i=0;i<10;i++){
|
||||
for (i = 0; i < 10; i++) { // NOT: for(i=0;i<10;i++){
|
||||
...
|
||||
|
||||
1.3. Namespaces should have the following form:
|
||||
@@ -52,11 +52,11 @@ extended it to C++.
|
||||
|
||||
} // namespace example
|
||||
|
||||
Note that code inside namespace is **not** indented. Avoid the following:
|
||||
Note that code inside the namespace is **not** indented. Avoid the following:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// NOT
|
||||
// WRONG
|
||||
//
|
||||
// namespace example {
|
||||
//
|
||||
@@ -180,7 +180,7 @@ extended it to C++.
|
||||
switch (condition) {
|
||||
case ABC: // 2 space indent
|
||||
statements; // 4 space indent
|
||||
NDN_CXX_FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
|
||||
case DEF:
|
||||
statements;
|
||||
@@ -211,7 +211,7 @@ extended it to C++.
|
||||
// Correct style
|
||||
case A1: {
|
||||
statements;
|
||||
NDN_CXX_FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
}
|
||||
|
||||
// Incorrect style: braces should cover the entire case block
|
||||
@@ -232,7 +232,7 @@ extended it to C++.
|
||||
switch (condition) {
|
||||
case ABC: // no indent
|
||||
statements; // 2 space indent
|
||||
NDN_CXX_FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
|
||||
case DEF:
|
||||
statements;
|
||||
@@ -243,11 +243,11 @@ extended it to C++.
|
||||
break;
|
||||
}
|
||||
|
||||
The ``NDN_CXX_FALLTHROUGH;`` annotation must be included whenever there is
|
||||
a case without a break statement. Leaving the break out is a common error,
|
||||
The ``[[fallthrough]]`` annotation must be included whenever there is a
|
||||
case without a break statement. Leaving the break out is a common error,
|
||||
and it must be made clear that it is intentional when it is not there.
|
||||
Moreover, modern compilers will warn when a case that falls through is not
|
||||
explicitly annotated.
|
||||
Moreover, modern compilers will warn when a case that falls through is
|
||||
not explicitly annotated.
|
||||
|
||||
1.11. A ``try-catch`` statement should have the following form:
|
||||
|
||||
@@ -329,19 +329,6 @@ should take the following form:
|
||||
statements;
|
||||
}
|
||||
|
||||
If the lambda has no parameters, ``()`` should be omitted.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
[&capture1, capture2] {
|
||||
statements;
|
||||
}
|
||||
|
||||
Either capture-default (``[&]`` or ``[=]``) is permitted, but its usage should be minimized.
|
||||
Only use a capture-default when it significantly simplifies code and improves readability.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
[&] (T arg) {
|
||||
statements;
|
||||
}
|
||||
@@ -350,8 +337,16 @@ should take the following form:
|
||||
statements;
|
||||
}
|
||||
|
||||
Trailing return type should be omitted whenever possible. Add it only when the compiler
|
||||
cannot deduce the return type automatically, or when it improves readability.
|
||||
If the lambda has no parameters, ``()`` should be omitted.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
[&capture1, capture2] {
|
||||
statements;
|
||||
}
|
||||
|
||||
Trailing return types should be omitted whenever possible. Add it only when the compiler
|
||||
cannot deduce the return type automatically, or when it improves readability. Note that
|
||||
``()`` is required by the C++ standard when ``mutable`` or a trailing return type is used.
|
||||
|
||||
.. code-block:: c++
|
||||
@@ -371,7 +366,7 @@ should take the following form:
|
||||
|
||||
[&capture1, capture2] (T1 arg1, T2 arg2) { statement; }
|
||||
|
||||
No-op can be written in a more compact form:
|
||||
A no-op lambda can be written in a more compact form:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
@@ -395,26 +390,20 @@ should take the following form:
|
||||
|
||||
T({arg1, arg2})
|
||||
|
||||
T object = {arg1, arg2};
|
||||
|
||||
class Class
|
||||
{
|
||||
private:
|
||||
T m_member = {arg1, arg2};
|
||||
T m_member{arg1, arg2};
|
||||
static T s_member = {arg1, arg2};
|
||||
};
|
||||
|
||||
Class::Class()
|
||||
: m_member{arg1, arg2}
|
||||
{
|
||||
}
|
||||
|
||||
T object = {arg1, arg2};
|
||||
|
||||
An empty braced-init-list is written as ``{}``. For example:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
T object{};
|
||||
|
||||
T object = {};
|
||||
|
||||
2. Naming Conventions
|
||||
@@ -490,13 +479,11 @@ written in mixed case starting with lower case.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
namespace model {
|
||||
namespace analyzer {
|
||||
namespace model::analyzer {
|
||||
|
||||
...
|
||||
|
||||
} // namespace analyzer
|
||||
} // namespace model
|
||||
} // namespace model::analyzer
|
||||
|
||||
2.7. Names representing generic template types should be a single uppercase letter.
|
||||
|
||||
@@ -530,8 +517,8 @@ written in mixed case starting with lower case.
|
||||
In general, the use of global variables should be avoided. Consider using singleton
|
||||
objects instead.
|
||||
|
||||
2.10. Private class variables should have ``m_`` prefix. Static class variables should have
|
||||
``s_`` prefix.
|
||||
2.10. All non-static data members of a class should be prefixed with ``m_`` unless they
|
||||
are public. Similarly, non-public static data members should be prefixed with ``s_``.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
@@ -629,13 +616,13 @@ symmetry.
|
||||
|
||||
::
|
||||
|
||||
get/set, add/remove, create/destroy, start/stop, insert/delete,
|
||||
get/set, add/remove, create/destroy, start/stop, insert/erase,
|
||||
increment/decrement, old/new, begin/end, first/last, up/down, min/max,
|
||||
next/previous (and commonly used next/prev), open/close, show/hide,
|
||||
suspend/resume, etc.
|
||||
|
||||
Pair ``insert/erase`` should be preferred. ``insert/delete`` can also be used if it
|
||||
does not conflict with C++ delete keyword.
|
||||
The pair ``insert/erase`` is preferred. ``insert/delete`` can also be used if it
|
||||
does not conflict with the ``delete`` keyword of C++.
|
||||
|
||||
2.21. Variable names should not include reference to variable type (do not use Hungarian
|
||||
notation).
|
||||
@@ -758,20 +745,29 @@ For example, the include section of ``ndn-cxx/foo/bar.cpp`` may look like this:
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
3.5. Types that are local to one file only can be declared inside that file.
|
||||
3.5. Definitions that are local to only one ``.cpp`` file should be declared inside that
|
||||
file and be placed in an unnamed namespace or declared ``static``.
|
||||
|
||||
3.6. Implicit conversion is generally allowed.
|
||||
|
||||
Implicit conversion between integer and floating point numbers can cause problems and
|
||||
should be avoided.
|
||||
|
||||
Implicit conversion in single-argument constructor is usually undesirable. Therefore, all
|
||||
single-argument constructors should be marked 'explicit', unless implicit conversion is
|
||||
desirable. In that case, a comment should document the reason.
|
||||
Implicit conversion in constructors that can be called with a single argument is usually
|
||||
undesirable. Therefore, all single-argument constructors should be marked ``explicit``,
|
||||
unless implicit conversion is desirable. In that case, a comment should document the
|
||||
reason for this.
|
||||
As an exception, copy and move constructors should not be explicit, since they do not
|
||||
perform type conversion.
|
||||
Constructors that cannot be called with a single argument may omit ``explicit``.
|
||||
Constructors that take a single ``std::initializer_list`` parameter should also omit
|
||||
``explicit``, in order to support copy-initialization.
|
||||
|
||||
Avoid C-style casts. Use ``static_cast``, ``dynamic_cast``, ``reinterpret_cast``,
|
||||
``const_cast`` instead where appropriate. Use ``static_pointer_cast``,
|
||||
``dynamic_pointer_cast``, ``const_pointer_cast`` when dealing with ``shared_ptr``.
|
||||
Avoid C-style casts.
|
||||
Use ``static_cast``, ``dynamic_cast``, ``const_cast``, ``reinterpret_cast``, or
|
||||
``bit_cast`` instead where appropriate.
|
||||
Use ``static_pointer_cast``, ``dynamic_pointer_cast``, or ``const_pointer_cast``
|
||||
when dealing with ``shared_ptr``.
|
||||
|
||||
3.7. Variables should be initialized where they are declared.
|
||||
|
||||
@@ -793,9 +789,9 @@ For example, the include section of ``ndn-cxx/foo/bar.cpp`` may look like this:
|
||||
|
||||
Exceptions to this rule:
|
||||
|
||||
* When the class is essentially a dumb data structure with no or minimal behavior
|
||||
(equivalent to a C struct, also known as POD type). In this case it is appropriate
|
||||
to make the instance variables public by using ``struct``.
|
||||
* When the class is essentially a passive data structure with no or minimal behavior
|
||||
(equivalent to a C struct, also known as POD type). In this case, all fields should
|
||||
be public and the keyword ``struct`` should be used instead of ``class``.
|
||||
|
||||
* When the class is used only inside the compilation unit, e.g., when implementing pImpl
|
||||
idiom (aka Bridge pattern) or similar cases.
|
||||
@@ -812,8 +808,11 @@ than to the name.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
if (nLines != 0) // NOT: if (nLines)
|
||||
if (value != 0.0) // NOT: if (value)
|
||||
if (nLines != 0) // NOT: if (nLines)
|
||||
|
||||
int* ptr = ...
|
||||
if (ptr) // OK
|
||||
if (ptr != nullptr) // also OK
|
||||
|
||||
3.11. *(removed)*
|
||||
|
||||
@@ -837,10 +836,10 @@ than to the name.
|
||||
|
||||
// NOT:
|
||||
for (;;) { // NO!
|
||||
:
|
||||
...
|
||||
}
|
||||
while (1) { // NO!
|
||||
:
|
||||
...
|
||||
}
|
||||
|
||||
3.14. Complex conditional expressions must be avoided. Introduce temporary boolean variables
|
||||
@@ -1004,10 +1003,10 @@ decimal, and without omitting 0 before the decimal point.
|
||||
int z = x + y;
|
||||
BOOST_ASSERT(z - y == x);
|
||||
|
||||
The expression passed to ``BOOST_ASSERT`` MUST NOT have side effects,
|
||||
because it MAY NOT be evaluated in release builds.
|
||||
The expression passed to ``BOOST_ASSERT`` must not have side effects,
|
||||
because it may not be evaluated in release builds.
|
||||
|
||||
3.28. Use ``static_assert`` for static assertions.
|
||||
3.28. Use ``static_assert`` for compile-time assertions.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
@@ -1022,43 +1021,32 @@ decimal, and without omitting 0 before the decimal point.
|
||||
static_assert(std::is_base_of<BaseClass, DerivedClass>::value,
|
||||
"DerivedClass must inherit from BaseClass");
|
||||
|
||||
3.29. ``auto`` type specifier MAY be used for local variables, if a human reader
|
||||
can easily deduce the actual type.
|
||||
3.29. The ``auto`` type specifier may be used for local variables if a human reader can
|
||||
easily deduce the actual type, or if it makes the code safer.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
std::vector<int> intVector;
|
||||
auto i = intVector.find(4);
|
||||
auto i = intVector.find(4); // OK
|
||||
|
||||
auto stringSet = std::make_shared<std::set<std::string>>();
|
||||
auto stringSet = std::make_shared<std::set<std::string>>(); // OK
|
||||
|
||||
``auto`` SHOULD NOT be used if a human reader cannot easily deduce the actual type.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
auto x = foo(); // BAD if the declaration of foo() isn't nearby
|
||||
|
||||
``const auto&`` SHOULD be used to represent constant reference types.
|
||||
``auto&&`` SHOULD be used to represent mutable reference types.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
std::list<std::string> strings;
|
||||
for (const auto& str : strings) {
|
||||
statements; // cannot modify `str`
|
||||
}
|
||||
for (auto&& str : strings) {
|
||||
statements; // can modify `str`
|
||||
std::vector<std::string> strings;
|
||||
for (const auto& str : strings) { // OK, iterating over the elements of a container
|
||||
std::cout << str;
|
||||
}
|
||||
|
||||
obj.onEvent([] (auto&&...) { std::cout << "hi!"; }); // OK, unused lambda parameters
|
||||
|
||||
auto x = foo(); // BAD unless foo() is declared nearby or has a well-known prototype
|
||||
|
||||
3.30. Use the ``override`` or ``final`` specifier when overriding a virtual
|
||||
member function or a virtual destructor.
|
||||
|
||||
``virtual`` MUST NOT be used along with ``final``, so that the compiler
|
||||
can generate an error when a final function does not override.
|
||||
``virtual`` must not be used along with ``final`` so that the compiler can generate
|
||||
an error when a final function does not override.
|
||||
|
||||
``virtual`` SHOULD NOT be used along with ``override``, for consistency
|
||||
with ``final``.
|
||||
``virtual`` should not be used along with ``override`` for consistency with ``final``.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
@@ -1085,5 +1073,22 @@ member function or a virtual destructor.
|
||||
|
||||
3.31. The recommended way to throw an exception derived from ``std::exception`` is to use
|
||||
``NDN_THROW`` or one of the other ``NDN_THROW_*`` macros.
|
||||
Exceptions thrown using these macros will be augmented with additional diagnostic information,
|
||||
including the file name, line number, and function name from which the exception was thrown.
|
||||
|
||||
Exceptions thrown using these macros will be augmented with additional diagnostic
|
||||
information, including the file name, line number, and function name from which
|
||||
the exception was thrown.
|
||||
|
||||
The extended diagnostic information contained in the exception can be printed with
|
||||
``boost::diagnostic_information()``.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#include <boost/exception/diagnostic_information.hpp>
|
||||
#include <iostream>
|
||||
|
||||
try {
|
||||
operationThatMayThrow();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << boost::diagnostic_information(e);
|
||||
}
|
||||
+35
-89
@@ -1,25 +1,17 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
import importlib.util
|
||||
import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
project = u'ndn-cxx: NDN C++ library with eXperimental eXtensions'
|
||||
copyright = u'Copyright © 2013-2020 Regents of the University of California.'
|
||||
author = u'Named Data Networking Project'
|
||||
project = 'ndn-cxx: NDN C++ library with eXperimental eXtensions'
|
||||
copyright = 'Copyright © 2013-2023 Regents of the University of California.'
|
||||
author = 'Named Data Networking Project'
|
||||
|
||||
# The short X.Y version.
|
||||
#version = ''
|
||||
@@ -35,49 +27,34 @@ today_fmt = '%Y-%m-%d'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#
|
||||
needs_sphinx = '1.3'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
needs_sphinx = '4.0'
|
||||
extensions = [
|
||||
'sphinx.ext.extlinks',
|
||||
'sphinx.ext.todo',
|
||||
]
|
||||
|
||||
def addExtensionIfExists(extension):
|
||||
def addExtensionIfExists(extension: str):
|
||||
try:
|
||||
__import__(extension)
|
||||
if importlib.util.find_spec(extension) is None:
|
||||
raise ModuleNotFoundError(extension)
|
||||
except (ImportError, ValueError):
|
||||
sys.stderr.write(f'WARNING: Extension {extension!r} not found. '
|
||||
'Some documentation may not build correctly.\n')
|
||||
else:
|
||||
extensions.append(extension)
|
||||
except ImportError:
|
||||
sys.stderr.write("Extension '%s' not found. "
|
||||
"Some documentation may not build correctly.\n" % extension)
|
||||
|
||||
addExtensionIfExists('sphinxcontrib.doxylink')
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = []
|
||||
exclude_patterns = ['Thumbs.db', '.DS_Store']
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'named_data_theme'
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
html_theme_path = ['.']
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
@@ -92,67 +69,36 @@ html_show_sourcelink = False
|
||||
highlight_language = 'none'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ------------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'ndn-cxx-docs.tex', u'NDN C++ library with eXperimental eXtensions',
|
||||
author, 'manual'),
|
||||
]
|
||||
|
||||
|
||||
# -- Options for manual page output ------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-manual-page-output
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('manpages/ndnsec', 'ndnsec', 'NDN security toolkit', None, 1),
|
||||
('manpages/ndnsec-cert-dump', 'ndnsec-cert-dump', 'export an NDN certificate', None, 1),
|
||||
('manpages/ndnsec-cert-gen', 'ndnsec-cert-gen', 'create an NDN certificate for an identity', None, 1),
|
||||
('manpages/ndnsec-cert-install', 'ndnsec-cert-install', 'import an NDN certificate from a file', None, 1),
|
||||
('manpages/ndnsec-delete', 'ndnsec-delete', 'delete an NDN identity, key, or certificate', None, 1),
|
||||
('manpages/ndnsec-export', 'ndnsec-export', 'export an NDN certificate and its private key to a file', None, 1),
|
||||
('manpages/ndnsec-get-default', 'ndnsec-get-default', 'show the default NDN identity, key, and certificate for the current user', None, 1),
|
||||
('manpages/ndnsec-import', 'ndnsec-import', 'import an NDN certificate and its private key from a file', None, 1),
|
||||
('manpages/ndnsec-key-gen', 'ndnsec-key-gen', 'generate an NDN key for an identity', None, 1),
|
||||
('manpages/ndnsec-list', 'ndnsec-list', 'list all known NDN identities, keys, and certificates', None, 1),
|
||||
('manpages/ndnsec-set-default', 'ndnsec-set-default', 'change the default NDN identity, key, or certificate for the current user', None, 1),
|
||||
('manpages/ndnsec-sign-req', 'ndnsec-sign-req', 'generate an NDN certificate signing request', None, 1),
|
||||
('manpages/ndnsec-unlock-tpm', 'ndnsec-unlock-tpm', 'unlock the TPM', None, 1),
|
||||
('manpages/ndn-client.conf', 'ndn-client.conf', 'configuration file for NDN applications', None, 5),
|
||||
('manpages/ndn-log', 'ndn-log', 'ndn-cxx logging', None, 7),
|
||||
('manpages/ndnsec', 'ndnsec', 'NDN security toolkit', [], 1),
|
||||
('manpages/ndnsec-cert-dump', 'ndnsec-cert-dump', 'export an NDN certificate', [], 1),
|
||||
('manpages/ndnsec-cert-gen', 'ndnsec-cert-gen', 'create an NDN certificate for an identity', [], 1),
|
||||
('manpages/ndnsec-cert-install', 'ndnsec-cert-install', 'import an NDN certificate from a file', [], 1),
|
||||
('manpages/ndnsec-delete', 'ndnsec-delete', 'delete an NDN identity, key, or certificate', [], 1),
|
||||
('manpages/ndnsec-export', 'ndnsec-export', 'export an NDN certificate and its private key to a file', [], 1),
|
||||
('manpages/ndnsec-get-default', 'ndnsec-get-default', 'show the default NDN identity, key, and certificate for the current user', [], 1),
|
||||
('manpages/ndnsec-import', 'ndnsec-import', 'import an NDN certificate and its private key from a file', [], 1),
|
||||
('manpages/ndnsec-key-gen', 'ndnsec-key-gen', 'generate an NDN key for an identity', [], 1),
|
||||
('manpages/ndnsec-list', 'ndnsec-list', 'list all known NDN identities, keys, and certificates', [], 1),
|
||||
('manpages/ndnsec-set-default', 'ndnsec-set-default', 'change the default NDN identity, key, or certificate for the current user', [], 1),
|
||||
('manpages/ndnsec-sign-req', 'ndnsec-sign-req', 'generate an NDN certificate signing request', [], 1),
|
||||
('manpages/ndnsec-unlock-tpm', 'ndnsec-unlock-tpm', 'unlock the TPM', [], 1),
|
||||
('manpages/ndn-client.conf', 'ndn-client.conf', 'configuration file for NDN applications', [], 5),
|
||||
('manpages/ndn-log', 'ndn-log', 'ndn-cxx logging', [], 7),
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = True
|
||||
|
||||
|
||||
# -- Custom options ----------------------------------------------------------
|
||||
# -- Misc options ------------------------------------------------------------
|
||||
|
||||
doxylink = {
|
||||
'ndn-cxx': ('ndn-cxx.tag', 'doxygen/'),
|
||||
}
|
||||
|
||||
extlinks = {
|
||||
'issue': ('https://redmine.named-data.net/issues/%s', 'issue #'),
|
||||
'issue': ('https://redmine.named-data.net/issues/%s', 'issue #%s'),
|
||||
}
|
||||
+6
-57
@@ -68,7 +68,7 @@ OUTPUT_DIRECTORY = docs/doxygen
|
||||
# performance problems for the file system.
|
||||
# The default value is: NO.
|
||||
|
||||
CREATE_SUBDIRS = YES
|
||||
CREATE_SUBDIRS = NO
|
||||
|
||||
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
|
||||
# characters to appear in the names of generated files. If set to NO, non-ASCII
|
||||
@@ -230,12 +230,6 @@ TAB_SIZE = 4
|
||||
|
||||
ALIASES =
|
||||
|
||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||
# will allow you to use the command class in the itcl::class meaning.
|
||||
|
||||
TCL_SUBST =
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
# instance, some of the names that are used will be different. The list of all
|
||||
@@ -443,7 +437,7 @@ EXTRACT_PACKAGE = NO
|
||||
# included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_STATIC = NO
|
||||
|
||||
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
|
||||
# locally in source files will be included in the documentation. If set to NO,
|
||||
@@ -780,7 +774,7 @@ WARN_LOGFILE =
|
||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = ndn-cxx
|
||||
INPUT = ndn-cxx build/ndn-cxx/version.hpp
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
@@ -836,7 +830,7 @@ EXCLUDE_SYMLINKS = NO
|
||||
# Note that the wildcards are matched against the file with absolute path, so to
|
||||
# exclude all test directories for example use the pattern */test/*
|
||||
|
||||
EXCLUDE_PATTERNS = */ndn-cxx/impl/* */ndn-cxx/*/impl/* */ndn-cxx/util/nonstd/*
|
||||
EXCLUDE_PATTERNS = */ndn-cxx/impl/* */ndn-cxx/*/impl/* */ndn-cxx/detail/nonstd/*
|
||||
|
||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||
@@ -1047,13 +1041,6 @@ VERBATIM_HEADERS = YES
|
||||
|
||||
ALPHABETICAL_INDEX = YES
|
||||
|
||||
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
|
||||
# which the alphabetical index list will be split.
|
||||
# Minimum value: 1, maximum value: 20, default value: 5.
|
||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
|
||||
# In case all classes in a project start with a common prefix, all classes will
|
||||
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
|
||||
# can be used to specify a prefix (or a list of prefixes) that should be ignored
|
||||
@@ -1191,7 +1178,7 @@ HTML_COLORSTYLE_GAMMA = 91
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_TIMESTAMP = YES
|
||||
HTML_TIMESTAMP = NO
|
||||
|
||||
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
|
||||
# documentation will contain sections that can be hidden and shown after the
|
||||
@@ -1752,16 +1739,6 @@ LATEX_BATCHMODE = NO
|
||||
|
||||
LATEX_HIDE_INDICES = NO
|
||||
|
||||
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
|
||||
# code with syntax highlighting in the LaTeX output.
|
||||
#
|
||||
# Note that which sources are shown also depends on other settings such as
|
||||
# SOURCE_BROWSER.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_SOURCE_CODE = NO
|
||||
|
||||
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
|
||||
# bibliography, e.g. plainnat, or ieeetr. See
|
||||
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
|
||||
@@ -1834,16 +1811,6 @@ RTF_STYLESHEET_FILE =
|
||||
|
||||
RTF_EXTENSIONS_FILE =
|
||||
|
||||
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
|
||||
# with syntax highlighting in the RTF output.
|
||||
#
|
||||
# Note that which sources are shown also depends on other settings such as
|
||||
# SOURCE_BROWSER.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||
|
||||
RTF_SOURCE_CODE = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -1933,15 +1900,6 @@ GENERATE_DOCBOOK = NO
|
||||
|
||||
DOCBOOK_OUTPUT = docbook
|
||||
|
||||
# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
|
||||
# program listings (including syntax highlighting and cross-referencing
|
||||
# information) to the DOCBOOK output. Note that enabling this will significantly
|
||||
# increase the size of the DOCBOOK output.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
|
||||
|
||||
DOCBOOK_PROGRAMLISTING = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -2132,15 +2090,6 @@ EXTERNAL_PAGES = YES
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
|
||||
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
|
||||
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
|
||||
# disabled, but it is recommended to install and use dot, since it yields more
|
||||
# powerful graphs.
|
||||
# The default value is: YES.
|
||||
|
||||
CLASS_DIAGRAMS = YES
|
||||
|
||||
# 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
|
||||
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
||||
@@ -2161,7 +2110,7 @@ HIDE_UNDOC_RELATIONS = YES
|
||||
# set to NO
|
||||
# The default value is: YES.
|
||||
|
||||
HAVE_DOT = YES
|
||||
HAVE_DOT = @HAVE_DOT@
|
||||
|
||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
||||
# to run in parallel. When set to 0 doxygen will base this on the number of
|
||||
|
||||
+10
-10
@@ -5,7 +5,7 @@ Trivial applications
|
||||
|
||||
To successfully run the following examples, please make sure that NFD is properly
|
||||
configured and running. For more information about NFD, refer to `NFD's official
|
||||
homepage <https://named-data.net/doc/NFD/>`_.
|
||||
homepage <https://docs.named-data.net/NFD/>`__.
|
||||
|
||||
Trivial consumer
|
||||
----------------
|
||||
@@ -18,7 +18,7 @@ callbacks to be called when Data/Nack is retrieved or Interest times out.
|
||||
.. literalinclude:: ../examples/consumer.cpp
|
||||
:language: c++
|
||||
:linenos:
|
||||
:emphasize-lines: 39-45,48,59,65,71
|
||||
:emphasize-lines: 43-48,51-54,62,76,82
|
||||
|
||||
Trivial producer
|
||||
----------------
|
||||
@@ -41,7 +41,7 @@ using :ndn-cxx:`Face::put` method.
|
||||
.. literalinclude:: ../examples/producer.cpp
|
||||
:language: c++
|
||||
:linenos:
|
||||
:emphasize-lines: 41,50,57-59,62,70,74
|
||||
:emphasize-lines: 39-42,55,60-63,78,86,90
|
||||
|
||||
Consumer that uses Scheduler
|
||||
----------------------------
|
||||
@@ -49,13 +49,13 @@ Consumer that uses Scheduler
|
||||
The following example demonstrates how to use :ndn-cxx:`Scheduler` to schedule arbitrary
|
||||
events for execution at specific points of time.
|
||||
|
||||
The library internally uses `boost::asio::io_service
|
||||
<https://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/reference/io_service.html>`_ to
|
||||
implement fully asynchronous NDN operations (i.e., sending and receiving Interests and
|
||||
Data). In addition to network-related operations, ``boost::asio::io_service`` can be used
|
||||
The library internally uses `boost::asio::io_context
|
||||
<https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/reference/io_context.html>`__
|
||||
to implement fully asynchronous NDN operations (i.e., sending and receiving Interests and
|
||||
Data). In addition to network-related operations, ``boost::asio::io_context`` can be used
|
||||
to execute any arbitrary callback within the processing thread (run either explicitly via
|
||||
``io_service::run()`` or implicitly via :ndn-cxx:`Face::processEvents` as in previous
|
||||
examples). :ndn-cxx:`Scheduler` is just a wrapper on top of ``io_service``, providing a
|
||||
``io_context::run()`` or implicitly via :ndn-cxx:`Face::processEvents` as in previous
|
||||
examples). :ndn-cxx:`Scheduler` is just a wrapper on top of ``io_context``, providing a
|
||||
simple interface to schedule tasks at specific times.
|
||||
|
||||
The highlighted lines in the example demonstrate all that is needed to express a second
|
||||
@@ -64,4 +64,4 @@ Interest approximately 3 seconds after the first one.
|
||||
.. literalinclude:: ../examples/consumer-with-timer.cpp
|
||||
:language: c++
|
||||
:linenos:
|
||||
:emphasize-lines: 39-40,56,62,93,106,114-116
|
||||
:emphasize-lines: 47-50,53,84,96-99,104-106
|
||||
+38
-34
@@ -1,26 +1,6 @@
|
||||
ndn-cxx: NDN C++ library with eXperimental eXtensions
|
||||
=====================================================
|
||||
|
||||
**ndn-cxx** is a C++14 library implementing Named Data Networking (NDN) primitives
|
||||
that can be used to write various NDN applications. The library is currently being
|
||||
used by the following projects:
|
||||
|
||||
* `NFD - NDN Forwarding Daemon <https://github.com/named-data/NFD>`_
|
||||
* `NLSR - Named-data Link-State Routing protocol <https://github.com/named-data/NLSR>`_
|
||||
* `ndn-tools - Essential NDN command-line tools <https://github.com/named-data/ndn-tools>`_
|
||||
* `repo-ng - Next generation of NDN repository <https://github.com/named-data/repo-ng>`_
|
||||
* `ChronoSync - Sync library for multiuser realtime applications <https://github.com/named-data/ChronoSync>`_
|
||||
* `PSync - Partial and full synchronization library <https://github.com/named-data/PSync>`_
|
||||
* `ndn-traffic-generator - Traffic generator for NDN <https://github.com/named-data/ndn-traffic-generator>`_
|
||||
* `NAC - Name-based Access Control <https://github.com/named-data/name-based-access-control>`_
|
||||
* `NDNS - Domain Name Service for NDN <https://github.com/named-data/ndns>`_
|
||||
|
||||
Please submit any bugs or feature requests to the `ndn-cxx issue tracker
|
||||
<https://redmine.named-data.net/projects/ndn-cxx/issues>`_.
|
||||
|
||||
ndn-cxx Documentation
|
||||
---------------------
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 3
|
||||
@@ -36,36 +16,60 @@ ndn-cxx Documentation
|
||||
:maxdepth: 1
|
||||
|
||||
code-style
|
||||
RELEASE_NOTES
|
||||
release-notes
|
||||
releases
|
||||
|
||||
**ndn-cxx** is a C++17 library implementing Named Data Networking (NDN) primitives
|
||||
that can be used to write various NDN applications. The library is currently being
|
||||
used by the following projects:
|
||||
|
||||
* `NFD - NDN Forwarding Daemon <https://github.com/named-data/NFD>`_
|
||||
* `NLSR - Named-data Link-State Routing protocol <https://github.com/named-data/NLSR>`_
|
||||
* `ndn-tools - Essential NDN command-line tools <https://github.com/named-data/ndn-tools>`_
|
||||
* `ndn-svs - State Vector Sync library <https://github.com/named-data/ndn-svs>`_
|
||||
* `PSync - Partial and full Sync library <https://github.com/named-data/PSync>`_
|
||||
* `ChronoSync - Sync library for distributed real-time applications (deprecated) <https://github.com/named-data/ChronoSync>`_
|
||||
* `NAC - Name-based Access Control library <https://github.com/named-data/name-based-access-control>`_
|
||||
* `NDNCERT - NDN certificate management protocol <https://github.com/named-data/ndncert>`_
|
||||
* `repo-ng - NDN repository implementation in C++ (deprecated) <https://github.com/named-data/repo-ng>`_
|
||||
* `ndn-traffic-generator - Simple NDN traffic generator <https://github.com/named-data/ndn-traffic-generator>`_
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
- :doc:`INSTALL`
|
||||
- :doc:`examples`
|
||||
- :doc:`tutorials`
|
||||
|
||||
+ `NDN Software Contributor's Guide <https://github.com/named-data/.github/blob/master/CONTRIBUTING.md>`_ (guide for newcomers to the NDN community of software generally)
|
||||
+ :doc:`tutorials/utils-ndn-regex`
|
||||
+ :doc:`tutorials/security-validator-config`
|
||||
|
||||
- :doc:`manpages`
|
||||
- :doc:`release-notes`
|
||||
- :doc:`releases`
|
||||
|
||||
For developers
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
- `NDN Software Contributor's Guide <https://github.com/named-data/.github/blob/main/CONTRIBUTING.md>`__
|
||||
(guide for newcomers to the NDN community of software)
|
||||
|
||||
- :doc:`specs`
|
||||
|
||||
+ :doc:`specs/signed-interest`
|
||||
+ :doc:`specs/certificate-format`
|
||||
+ :doc:`specs/safe-bag`
|
||||
+ :doc:`specs/validation-error-code`
|
||||
+ :doc:`specs/signed-interest`
|
||||
|
||||
- :doc:`manpages`
|
||||
|
||||
Additional Documentation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- `API documentation (doxygen) <doxygen/annotated.html>`_
|
||||
- `API documentation (doxygen) <doxygen/annotated.html>`__
|
||||
- :doc:`code-style`
|
||||
- :doc:`RELEASE_NOTES`
|
||||
- :doc:`releases`
|
||||
|
||||
Issues
|
||||
------
|
||||
|
||||
Please submit any bug reports or feature requests to the
|
||||
`ndn-cxx issue tracker <https://redmine.named-data.net/projects/ndn-cxx/issues>`__.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
ndn-cxx is an open source project licensed under the LGPL version 3. For more information about
|
||||
the license, refer to `COPYING.md <https://github.com/named-data/ndn-cxx/blob/master/COPYING.md>`_.
|
||||
the license, refer to `COPYING.md <https://github.com/named-data/ndn-cxx/blob/master/COPYING.md>`__.
|
||||
+8
-18
@@ -1,20 +1,10 @@
|
||||
Manpages
|
||||
========
|
||||
Man pages
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
ndn-client.conf <manpages/ndn-client.conf>
|
||||
ndn-cxx logging <manpages/ndn-log>
|
||||
manpages/ndnsec
|
||||
ndnsec-list <manpages/ndnsec-list>
|
||||
ndnsec-get-default <manpages/ndnsec-get-default>
|
||||
ndnsec-set-default <manpages/ndnsec-set-default>
|
||||
ndnsec-key-gen <manpages/ndnsec-key-gen>
|
||||
ndnsec-sign-req <manpages/ndnsec-sign-req>
|
||||
ndnsec-cert-gen <manpages/ndnsec-cert-gen>
|
||||
ndnsec-cert-install <manpages/ndnsec-cert-install>
|
||||
ndnsec-cert-dump <manpages/ndnsec-cert-dump>
|
||||
ndnsec-delete <manpages/ndnsec-delete>
|
||||
ndnsec-export <manpages/ndnsec-export>
|
||||
ndnsec-import <manpages/ndnsec-import>
|
||||
ndnsec-unlock-tpm <manpages/ndnsec-unlock-tpm>
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
:maxdepth: 1
|
||||
|
||||
ndn-client.conf <manpages/ndn-client.conf>
|
||||
ndn-log: ndn-cxx logging <manpages/ndn-log>
|
||||
manpages/ndnsec*
|
||||
@@ -1,6 +1,9 @@
|
||||
client.conf
|
||||
===========
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
System configuration of NDN platform is specified in ``client.conf``.
|
||||
|
||||
The configuration file ``client.conf`` is looked up in several directories in the following order:
|
||||
@@ -13,11 +16,11 @@ The configuration file ``client.conf`` is looked up in several directories in th
|
||||
Here is an example of ``client.conf`` for the current ndn-cxx package:
|
||||
|
||||
.. literalinclude:: ../../client.conf.sample
|
||||
:language: ini
|
||||
:language: ini
|
||||
|
||||
|
||||
NFD
|
||||
---
|
||||
Forwarder
|
||||
---------
|
||||
|
||||
transport
|
||||
FaceUri for default connection toward local NDN forwarder. Only ``unix``, ``tcp``, ``tcp4``, and
|
||||
@@ -38,17 +41,17 @@ pib
|
||||
|
||||
pib=[scheme]:[location]
|
||||
|
||||
Possible values for ``[scheme]``:
|
||||
Possible values for ``[scheme]`` are:
|
||||
|
||||
* ``pib-sqlite3``: local PIB implementation with SQLite3 storage engine
|
||||
* ``pib-sqlite3``: local PIB implementation using the SQLite3 storage engine.
|
||||
|
||||
Possible values for ``[location]``:
|
||||
|
||||
* absolute path where SQLite3 database will be stored
|
||||
* relative path (relative to ``config.conf``)
|
||||
* empty: default path ``$HOME/.ndn`` will be used
|
||||
* absolute path where the SQLite3 database will be stored
|
||||
* relative path (relative to ``client.conf``)
|
||||
* empty: the default path ``$HOME/.ndn`` will be used
|
||||
|
||||
When ``[location]`` is empty, trailing ``:`` can be omitted. For example::
|
||||
When ``[location]`` is empty, the trailing ``:`` can be omitted. For example::
|
||||
|
||||
pib=pib-sqlite3
|
||||
|
||||
@@ -70,12 +73,12 @@ tpm
|
||||
|
||||
tpm=[scheme]:[location]
|
||||
|
||||
Possible values for ``[scheme]``:
|
||||
Possible values for ``[scheme]`` are:
|
||||
|
||||
* ``tpm-osx-keychain`` (default on macOS): secure storage of private keys in the macOS
|
||||
* ``tpm-osxkeychain`` (default on macOS): secure storage of private keys in the macOS
|
||||
Keychain with OS-provided access restrictions.
|
||||
|
||||
``[location]`` parameter is ignored.
|
||||
The ``[location]`` parameter is ignored.
|
||||
|
||||
May not work for daemon applications, as user interaction may be required to access the
|
||||
macOS Keychain.
|
||||
@@ -86,10 +89,10 @@ tpm
|
||||
|
||||
* absolute path to directory that will store private/public key files (unencrypted with
|
||||
``0700`` permission)
|
||||
* relative path (relative to ``config.conf``)
|
||||
* empty: default path ``$HOME/.ndn/ndnsec-tpm-file`` will be used
|
||||
* relative path (relative to ``client.conf``)
|
||||
* empty: the default path ``$HOME/.ndn/ndnsec-tpm-file`` will be used
|
||||
|
||||
When ``[location]`` is empty, trailing ``:`` can be omitted. For example::
|
||||
When ``[location]`` is empty, the trailing ``:`` can be omitted. For example::
|
||||
|
||||
tpm=tpm-file
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
ndn-log
|
||||
=======
|
||||
ndn-cxx logging
|
||||
===============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The ndn-cxx logging facility exposes the internal state of NDN libraries and
|
||||
applications so the user can investigate internal interactions, such as interest
|
||||
@@ -8,8 +11,8 @@ sync and recovery Interest processing inside ChronoSync, etc. During runtime, th
|
||||
user is able to specify the types of messages he or she would like to receive from
|
||||
a set of logging modules pre-configured by library and application developers.
|
||||
|
||||
Environment Variable
|
||||
--------------------
|
||||
Environment
|
||||
-----------
|
||||
|
||||
One way to control ndn-cxx logging facility is through the environment variable
|
||||
``NDN_LOG``. Using this variable, one can set the log levels for the available logging
|
||||
|
||||
@@ -11,7 +11,7 @@ Description
|
||||
-----------
|
||||
|
||||
:program:`ndnsec-cert-dump` reads a certificate from the **Public Info Base (PIB)**
|
||||
or from a file, and prints it on the standard output.
|
||||
or from a file, and prints it on the standard output in Base64 encoding.
|
||||
|
||||
By default, *name* is interpreted as a certificate name.
|
||||
|
||||
@@ -44,22 +44,21 @@ Dump a certificate from PIB to standard output::
|
||||
|
||||
$ ndnsec-cert-dump /ndn/test/david/KEY/ksk-1396913058196/ID-CERT/%00%00%01E%3E%9D%A0%DE
|
||||
|
||||
Dump a certificate in human-readable format::
|
||||
Print the NDN testbed root certificate in human-readable format::
|
||||
|
||||
$ ndnsec-cert-dump -p /ndn/test/david/KEY/ksk-1396913058196/ID-CERT/%00%00%01E%3E%9D%A0%DE
|
||||
Certificate name:
|
||||
/ndn/test/david/KEY/ksk-1396913058196/ID-CERT/%00%00%01E%3E%9D%A0%DE
|
||||
$ curl -A ndnsec -fsLS https://named-data.net/ndnsec/ndn-testbed-root.ndncert.x3.base64 | ndnsec-cert-dump -fp -
|
||||
Certificate Name:
|
||||
/ndn/KEY/%EC%F1L%8EQ%23%15%E0/ndn/%FD%00%00%01u%E6%7F2%10
|
||||
Additional Description:
|
||||
fullname: NDN Testbed Root X3
|
||||
Public Key:
|
||||
Key Type: 256-bit EC
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGx+3Y4FvYo1eScIvgD74lQhQdzN4
|
||||
zq021dop8t7kGfEpfGdKf2HGpnn4/qoF9iJ1yUZE/7Na8zzO4xT6RpIM0Q==
|
||||
Validity:
|
||||
NotBefore: 20140401T000000
|
||||
NotAfter: 20150331T235959
|
||||
Subject Description:
|
||||
2.5.4.41: David
|
||||
2.5.4.10: Some Organization
|
||||
Public key bits:
|
||||
MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAtLq50tpynJ15zExEh9l6
|
||||
jvh/HOmwhOppr/hTEPYUn2VTh21+JJIg5pHAAH/DQr8Bq5BGrdDUCIShxSxbaHwu
|
||||
a1y4XgKP1MYBQP/WzcIhIzB/3PBDdmE0jM3Qg6yuk8BOwett3C07GtwW9dfgacwt
|
||||
aC29xIHnYKfryH/gBSIDUIb38M7ILIDgQeIiQcHGHoFO8CbDtKY2OvVkFNgxowAR
|
||||
Xn+gtkIfMdE77Z8p0S21pYfdvPuIpVVLy7lnFdwGzyCi3nmbtd/r9NSTepBczWQz
|
||||
zBbThT7yfeNyHWLu0PZPdz84UpNPsBad3Bx9tT31noIVnt8yyBEfEU1jyEIVkm8U
|
||||
VQIB
|
||||
Not Before: 2020-11-20T16:31:37
|
||||
Not After: 2024-12-31T23:59:59
|
||||
Signature Information:
|
||||
Signature Type: SignatureSha256WithEcdsa
|
||||
Key Locator: Name=/ndn/KEY/%EC%F1L%8EQ%23%15%E0
|
||||
Self-Signed: yes
|
||||
@@ -74,18 +74,19 @@ Example
|
||||
YXL9AgIHRm9vIEJhchdHMEUCIQDPT9Hq1kvkE0r9W1aYSBVTnHlTEzgtz+v1DwkC
|
||||
ug/vLAIgY3xJITCwf55sqey33q5GIQSk1TRCkNNl58ojvPs5sNU=
|
||||
|
||||
$ ndnsec-dump-certificate -p -f signed.cert
|
||||
Certificate name:
|
||||
$ ndnsec-cert-dump -p -f signed.cert
|
||||
Certificate Name:
|
||||
/example/KEY/%E4%14%99%7F%28%96%82%EB/Universe/%FD%00%00%01q%D1%02N%82
|
||||
Validity:
|
||||
NotBefore: 20200501T000000
|
||||
NotAfter: 20210101T000000
|
||||
Additional Description:
|
||||
affiliation: Some Organization
|
||||
foobar: Foo Bar
|
||||
Public key bits:
|
||||
Public Key:
|
||||
Key Type: 256-bit EC
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOkmwKS8TlEyPFFV3IrpbrP4WgKr6
|
||||
pEQSf+zF/6faCeyXbmqbU1qsJ9IZ/3rMgnL0FED1u24wx65aUA3/Ka8wXA==
|
||||
Validity:
|
||||
Not Before: 2020-05-01T00:00:00
|
||||
Not After: 2021-01-01T00:00:00
|
||||
Signature Information:
|
||||
Signature Type: SignatureSha256WithEcdsa
|
||||
Key Locator: Name=/ndn/test/KEY/I%3FS%9A%28%BB%9A%95
|
||||
@@ -14,8 +14,9 @@ Description
|
||||
will be set as the default certificate for the corresponding identity and
|
||||
the identity will be set as the user's default identity.
|
||||
|
||||
*file* can be a filesystem path or an HTTP URL of a file containing the certificate
|
||||
to install. If *file* is "-", the certificate will be read from the standard input.
|
||||
*file* is a path to a file that contains the certificate to install.
|
||||
If *file* is "-", the certificate will be read from the standard input.
|
||||
The certificate should be in Base64 encoding.
|
||||
|
||||
Options
|
||||
-------
|
||||
@@ -41,10 +42,6 @@ Install a certificate and set it as the default certificate::
|
||||
|
||||
$ ndnsec-cert-install cert_file.cert
|
||||
|
||||
Install a certificate via HTTP and set it as the default certificate::
|
||||
|
||||
$ ndnsec-install-cert "http://ndncert.domain.com/cert/get/my-certificate.ndncert"
|
||||
|
||||
Install a certificate but do not change any default settings::
|
||||
|
||||
$ ndnsec-cert-install -N cert_file.cert
|
||||
+14
-25
@@ -21,51 +21,40 @@ provides a command-line interface for managing and using the NDN security data.
|
||||
Commands
|
||||
--------
|
||||
|
||||
list_
|
||||
The following commands are understood:
|
||||
|
||||
:doc:`list <ndnsec-list>`
|
||||
List all known identities/keys/certificates.
|
||||
|
||||
get-default_
|
||||
:doc:`get-default <ndnsec-get-default>`
|
||||
Show the default identity/key/certificate.
|
||||
|
||||
set-default_
|
||||
:doc:`set-default <ndnsec-set-default>`
|
||||
Change the default identity/key/certificate.
|
||||
|
||||
delete_
|
||||
:doc:`delete <ndnsec-delete>`
|
||||
Delete an identity/key/certificate.
|
||||
|
||||
key-gen_
|
||||
:doc:`key-gen <ndnsec-key-gen>`
|
||||
Generate a key for an identity.
|
||||
|
||||
sign-req_
|
||||
:doc:`sign-req <ndnsec-sign-req>`
|
||||
Generate a certificate signing request.
|
||||
|
||||
cert-gen_
|
||||
:doc:`cert-gen <ndnsec-cert-gen>`
|
||||
Create a certificate for an identity.
|
||||
|
||||
cert-dump_
|
||||
:doc:`cert-dump <ndnsec-cert-dump>`
|
||||
Export a certificate.
|
||||
|
||||
cert-install_
|
||||
:doc:`cert-install <ndnsec-cert-install>`
|
||||
Import a certificate from a file.
|
||||
|
||||
export_
|
||||
:doc:`export <ndnsec-export>`
|
||||
Export an identity as a SafeBag.
|
||||
|
||||
import_
|
||||
:doc:`import <ndnsec-import>`
|
||||
Import an identity from a SafeBag.
|
||||
|
||||
unlock-tpm_
|
||||
:doc:`unlock-tpm <ndnsec-unlock-tpm>`
|
||||
Unlock the TPM.
|
||||
|
||||
.. _list: ndnsec-list.html
|
||||
.. _get-default: ndnsec-get-default.html
|
||||
.. _set-default: ndnsec-set-default.html
|
||||
.. _delete: ndnsec-delete.html
|
||||
.. _key-gen: ndnsec-key-gen.html
|
||||
.. _sign-req: ndnsec-sign-req.html
|
||||
.. _cert-gen: ndnsec-cert-gen.html
|
||||
.. _cert-dump: ndnsec-cert-dump.html
|
||||
.. _cert-install: ndnsec-cert-install.html
|
||||
.. _export: ndnsec-export.html
|
||||
.. _import: ndnsec-import.html
|
||||
.. _unlock-tpm: ndnsec-unlock-tpm.html
|
||||
@@ -26,13 +26,13 @@ $mathjax
|
||||
<div class="row">
|
||||
<div class="three columns">
|
||||
<div id="logo">
|
||||
<a href="http://named-data.net" title="A Future Internet Architecture"><img src="http://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
|
||||
<a href="https://named-data.net" title="A Future Internet Architecture"><img src="https://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
|
||||
</div><!--logo end-->
|
||||
</div>
|
||||
|
||||
<!--top menu-->
|
||||
<div class="nine columns" id="menu_container" >
|
||||
<h1><a href="http://named-data.net/doc/ndn-cxx/$projectnumber/">$projectname $projectnumber documentation</a></h1>
|
||||
<h1><a href="https://docs.named-data.net/ndn-cxx/$projectnumber/">$projectname $projectnumber documentation</a></h1>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--header container end-->
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
release-notes/release-notes-0.7.1.rst
|
||||
@@ -0,0 +1,4 @@
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
.. include:: release-notes/release-notes-0.8.1.rst
|
||||
@@ -35,7 +35,7 @@ The current features include:
|
||||
|
||||
- **Wire format**
|
||||
|
||||
+ Full support of `NDN-TLV packet format v0.1 <https://named-data.net/doc/NDN-packet-spec/0.1/>`_
|
||||
+ Full support of `NDN-TLV packet format v0.1 <https://docs.named-data.net/NDN-packet-spec/0.1/>`__
|
||||
+ Pure C++ implementation of wire encoding/decoding with simple access to wire format
|
||||
of all NDN packet abstractions via ``wireEncode`` and ``wireDecode`` methods
|
||||
|
||||
|
||||
@@ -37,14 +37,14 @@ New features
|
||||
|
||||
+ New :ndn-cxx:`SignatureSha256WithEcdsa` signature type
|
||||
|
||||
+ Updates in :ndn-cxx:`Signature` data structure to reflect changes in `NDN-TLV spec
|
||||
0.1.1 <https://named-data.net/doc/NDN-packet-spec/0.1.1/>`_
|
||||
+ Updates in ``Signature`` data structure to reflect changes in the `NDN-TLV spec v0.1.1
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.1.1/>`__
|
||||
|
||||
- **Wire encoding**
|
||||
|
||||
+ ``Data::getFullName()`` method to get the Data packet name including the implicit digest
|
||||
+ :ndn-cxx:`Data::getFullName` method to get the Data packet name including the implicit digest
|
||||
|
||||
+ ``Name::getSuccessor()`` method to get name successor (:issue:`1677`)
|
||||
+ :ndn-cxx:`Name::getSuccessor` method to get name successor (:issue:`1677`)
|
||||
|
||||
+ New in-wire refreshing of Interest's nonce (:issue:`1758`)
|
||||
|
||||
@@ -66,7 +66,7 @@ New features
|
||||
+ Introduce ``util::EventEmitter``, :ndn-cxx:`util::NotificationSubscriber`,
|
||||
:ndn-cxx:`util::NotificationStream`, and :ndn-cxx:`nfd::FaceMonitor` utility classes
|
||||
|
||||
+ Introduce :ndn-cxx:`util::SegmentFetcher` helper class to fetch multi-segmented data
|
||||
+ Introduce :ndn-cxx:`SegmentFetcher` helper class to fetch multi-segmented data
|
||||
(:issue:`1879`)
|
||||
|
||||
- **Build**
|
||||
@@ -78,7 +78,7 @@ Updates and bug fixes
|
||||
|
||||
- **Base**
|
||||
|
||||
+ Serialization of socket write operations (:issue:`1707`)
|
||||
+ Serialization of socket write operations (:issue:`1769`)
|
||||
|
||||
+ Enforcing limit on Interest and Data packet size in :ndn-cxx:`Face::expressInterest` and
|
||||
:ndn-cxx:`Face::put` methods (:issue:`1774`)
|
||||
@@ -86,7 +86,7 @@ Updates and bug fixes
|
||||
+ Cleaning up transport state on communication failure, so Face can try to reconnect
|
||||
in the future
|
||||
|
||||
+ Fix bug in ``Face::removePendingInterest`` (:issue:`1917`)
|
||||
+ Fix bug in ``Face::removePendingInterest()`` (:issue:`1917`)
|
||||
|
||||
- **Wire encoding**
|
||||
|
||||
@@ -111,8 +111,8 @@ Updates and bug fixes
|
||||
+ Allow user to explicitly specify the cert name prefix before 'KEY' component in
|
||||
``ndnsec-certgen``
|
||||
|
||||
+ ``SignatureSha256`` has been renamed to :ndn-cxx:`DigestSha256` to conform to
|
||||
`NDN-TLV specification <https://named-data.net/doc/NDN-packet-spec/0.1.1/>`_
|
||||
+ ``SignatureSha256`` has been renamed to :ndn-cxx:`DigestSha256` to conform to the
|
||||
`NDN-TLV specification <https://docs.named-data.net/NDN-packet-spec/0.1.1/>`__
|
||||
|
||||
+ Add checking of Timestamp and Nonce fields in signed Interest within
|
||||
:ndn-cxx:`ValidatorConfig`
|
||||
@@ -145,7 +145,7 @@ Deprecated
|
||||
|
||||
Use versions that accept reference to ``io_service`` object.
|
||||
|
||||
- ``Face::ioService`` method, use :ndn-cxx:`Face::getIoService` instead.
|
||||
- ``Face::ioService`` method, use ``Face::getIoService`` instead.
|
||||
|
||||
- :ndn-cxx:`Interest` constructor that accepts name, individual selectors, and individual
|
||||
guiders as constructor parameters.
|
||||
|
||||
@@ -112,8 +112,8 @@ Deprecated
|
||||
``ndn::CertificateExtension``, ``ndn::CertificateSubjectDescription``. When necessary, use
|
||||
``security::v1::PublicKey``, ``security::v1::Certificate``, ``security::v1::IdentityCertificate``,
|
||||
``security::v1::CertificateExtension``, ``security::v1::CertificateSubjectDescription`` instead.
|
||||
The next release will feature :doc:`a new version of NDN Certificate format
|
||||
<../specs/certificate-format>`.
|
||||
The next release will feature `a new version of the NDN Certificate format
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.3/certificate.html>`__.
|
||||
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
@@ -13,19 +13,19 @@ Changes since version 0.5.0:
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- Add version 2 of the security framework (introduced in ``security::v2`` namespace)
|
||||
- Add version 2 of the security framework in ``security::v2`` namespace
|
||||
|
||||
* :ref:`NDN Certificate Format Version 2.0 <NDN Certificate Format Version 2.0>`
|
||||
(:issue:`3103`)
|
||||
* New Public Information Base (PIB) and Trusted Program Module (TPM) framework to manage
|
||||
* `NDN Certificate Format version 2.0
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.3/certificate.html>`__ (:issue:`3103`)
|
||||
* New Public Information Base (PIB) and Trusted Platform Module (TPM) framework to manage
|
||||
public/private keys and NDN Certificate version 2.0 (:issue:`2948`, :issue:`3202`)
|
||||
* New KeyChain implementation (:issue:`2926`)
|
||||
* New Validator implementation (:issue:`3289`, :issue:`1872`)
|
||||
* New security-supporting utilities: trust anchor container and certificate cache
|
||||
* Creation of `Command Interests
|
||||
<https://redmine.named-data.net/projects/ndn-cxx/wiki/CommandInterest>`__ delegated to
|
||||
:ndn-cxx:`CommandInterestSigner` class, while the new KeyChain only :ref:`signs Interests
|
||||
<Signed Interest>` (:issue:`3912`)
|
||||
``CommandInterestSigner`` class, while the new KeyChain only :doc:`signs Interests
|
||||
</specs/signed-interest>` (:issue:`3912`)
|
||||
|
||||
- Enable validator to fetch certificates directly from the signed/command interest sender
|
||||
(:issue:`3921`)
|
||||
@@ -63,27 +63,27 @@ Improvements and bug fixes
|
||||
Deprecated
|
||||
^^^^^^^^^^
|
||||
|
||||
- Old security framework. All old security framework classes are moved to
|
||||
- Old security framework. All old security framework classes are moved to the
|
||||
``ndn::security::v1`` namespace in this release and will be removed in the next release.
|
||||
|
||||
* ``v1::KeyChain``, use :ndn-cxx:`v2::KeyChain` instead
|
||||
* ``v1::KeyChain``; use ``v2::KeyChain`` instead.
|
||||
|
||||
* ``v1::Validator`` interface and all implementations of this interface (``ValidatorRegex``,
|
||||
``ValidatorConfig``, ``ValidatorNull``). Use :ndn-cxx:`v2::Validator` and the
|
||||
corresponding implementations of :ndn-cxx:`ValidationPolicy` interfaces (will be introduced
|
||||
before 0.6.0 release).
|
||||
``ValidatorConfig``, ``ValidatorNull``). Use ``v2::Validator`` and the corresponding
|
||||
implementations of :ndn-cxx:`ValidationPolicy` interfaces (will be introduced before
|
||||
the 0.6.0 release).
|
||||
|
||||
* ``v1::SecPublicInfo`` and its implementation (``SecPublicInfoSqlite``), ``SecTpm`` and its
|
||||
implementations (``SecTpmFile``, ``SecTpmOsx``). These classes are internal implementation
|
||||
and not intended to be used without ``v1::KeyChain``. :ndn-cxx:`v2::KeyChain` internally
|
||||
uses the newly introduced :ndn-cxx:`Pib` and :ndn-cxx:`Tpm` interfaces with their
|
||||
corresponding implementations.
|
||||
and not intended to be used without ``v1::KeyChain``. ``v2::KeyChain`` internally uses
|
||||
the newly introduced :ndn-cxx:`Pib` and :ndn-cxx:`Tpm` interfaces with their corresponding
|
||||
implementations.
|
||||
|
||||
* ``v1::Certificate``, ``v1::IdentityCertificate``, ``v1::CertificateExtension``,
|
||||
``v1::CertificateSubjectDescription``, use :ndn-cxx:`v2::Certificate` and
|
||||
:ndn-cxx:`AdditionalDescription`
|
||||
``v1::CertificateSubjectDescription``; use ``v2::Certificate`` and ``AdditionalDescription``
|
||||
instead.
|
||||
|
||||
* ``v1::SecuredBag``, use ``v2::SafeBag`` instead
|
||||
* ``v1::SecuredBag``; use :ndn-cxx:`SafeBag` instead.
|
||||
|
||||
- Constant ``io::BASE_64``, use ``io::BASE64`` instead (:issue:`3741`)
|
||||
|
||||
@@ -100,5 +100,3 @@ Deprecated
|
||||
``ndn::CertificateExtension``, ``ndn::CertificateSubjectDescription``. When necessary, use
|
||||
``security::v1::PublicKey``, ``security::v1::Certificate``, ``security::v1::IdentityCertificate``,
|
||||
``security::v1::CertificateExtension``, ``security::v1::CertificateSubjectDescription`` instead.
|
||||
The next release will feature :ref:`a new version of NDN Certificate format
|
||||
<NDN Certificate Format Version 2.0>`.
|
||||
@@ -11,12 +11,12 @@ New features
|
||||
- **(breaking change)** Security framework version 2 (:issue:`3098`, :issue:`3920`,
|
||||
:issue:`3644`, :issue:`4085`, :issue:`4323`, :issue:`4339`).
|
||||
|
||||
The released version of the library only supports the new version of the security (v2
|
||||
certificate format) and features a number of updates of KeyChain and Validator
|
||||
interfaces. At the same time, management APIs for :ndn-cxx:`ValidatorConfig` remained
|
||||
intact; transition to the new framework would require only adjusting
|
||||
:ndn-cxx:`Validator::validate` calls and updating configuration files to follow the new
|
||||
naming conventions of :ref:`NDN Certificate Format Version 2.0`.
|
||||
This release of the library supports only the new version of the security framework
|
||||
and features a number of updates to the KeyChain and Validator interfaces.
|
||||
At the same time, management APIs for :ndn-cxx:`ValidatorConfig` remained intact;
|
||||
transition to the new framework only requires adjusting :ndn-cxx:`Validator::validate`
|
||||
calls and updating configuration files to follow the naming conventions of the new
|
||||
`Certificate format <https://docs.named-data.net/NDN-packet-spec/0.3/certificate.html>`__.
|
||||
|
||||
- Integration of fetching certificates using Certificate Bundle as part of specialized
|
||||
``CertificateFetcher`` (:issue:`3891`)
|
||||
@@ -25,7 +25,7 @@ New features
|
||||
to include ``ForwardingHint`` instead of ``LinkObject``, following the latest NDN
|
||||
specification updates (:issue:`4054`, :issue:`4055`)
|
||||
|
||||
- Fine-grained signals on interface/address changes in NetworkMonitor
|
||||
- Fine-grained signals on interface/address changes in :ndn-cxx:`NetworkMonitor`
|
||||
for all supported platforms (:issue:`3353`, :issue:`4025`, :issue:`3817`, :issue:`4024`)
|
||||
|
||||
- Addition of ``TxSequence`` field and ``Ack``, the first repeatable field in
|
||||
@@ -51,7 +51,7 @@ Improvements and bug fixes
|
||||
|
||||
- FaceUri now accepts link-local IPv6 addresses (:issue:`1428`)
|
||||
|
||||
- Rename variables in ``FaceStatus`` and ``ForwarderStatus`` ('datas' => 'data')
|
||||
- Rename fields in :ndn-cxx:`FaceStatus` and :ndn-cxx:`ForwarderStatus` ('datas' => 'data')
|
||||
(:issue:`3955`)
|
||||
|
||||
- Improve logging framework and its uses
|
||||
@@ -63,19 +63,19 @@ Improvements and bug fixes
|
||||
* Add logging capabilities to ``Face``, ``UnixTransport``, ``TcpTransport``, and the new
|
||||
security framework (:issue:`3563`)
|
||||
|
||||
To enable logging, set environment variable ``NDN_LOG`` to enable specific, subset, or all
|
||||
logging module at appropriate levels. Examples:
|
||||
To configure logging, set the environment variable :doc:`NDN_LOG </manpages/ndn-log>`.
|
||||
Examples:
|
||||
|
||||
::
|
||||
.. code-block:: sh
|
||||
|
||||
export NDN_LOG=*=ALL
|
||||
export NDN_LOG=ndn.*=ALL
|
||||
export NDN_LOG=ndn.security=DEBUG:ndn.TcpTransport=ALL
|
||||
export NDN_LOG="*=ALL"
|
||||
export NDN_LOG="ndn.*=ALL"
|
||||
export NDN_LOG="ndn.security=DEBUG:ndn.TcpTransport=ALL"
|
||||
|
||||
- Ensure that ``Face`` sends ``Nack`` only after every ``InterestCallback`` has responded
|
||||
(:issue:`4228`)
|
||||
- Ensure that :ndn-cxx:`Face` sends a ``Nack`` only after every ``InterestCallback`` has
|
||||
responded (:issue:`4228`)
|
||||
|
||||
- Fix potential overflow in ``time::toIsoString`` (:issue:`3915`)
|
||||
- Fix potential overflow in :ndn-cxx:`time::toIsoString` (:issue:`3915`)
|
||||
|
||||
- Fix potentially misaligned memory accesses (:issue:`4172`, :issue:`4097`, :issue:`4175`,
|
||||
:issue:`4190`, :issue:`4191`)
|
||||
@@ -86,20 +86,15 @@ Improvements and bug fixes
|
||||
|
||||
- Source/header reorganization (:issue:`3940`)
|
||||
|
||||
* Move network-related files to ``src/net``
|
||||
* Move network-related files to ``src/net``. Note the following namespace changes:
|
||||
|
||||
.. note::
|
||||
Namespace changes
|
||||
+ ``ndn::util::FaceUri`` is now ``ndn::FaceUri``
|
||||
+ ``ndn::util::ethernet`` is now ``ndn::ethernet``
|
||||
+ ``ndn::util::NetworkMonitor`` and related classes are now in ``ndn::net``
|
||||
|
||||
* ndn::util::FaceUri is now ndn::FaceUri
|
||||
* ndn::util::ethernet is now ndn::ethernet
|
||||
* ndn::util::NetworkMonitor and related classes are now in ndn::net
|
||||
|
||||
* Move signal-related files into ``src/util/signal/`` directory, except for
|
||||
* Move signal-related files into ``src/util/signal`` directory, except for
|
||||
the main include ``signal.hpp``
|
||||
|
||||
* Move InMemoryStorage to ``src/ims``
|
||||
|
||||
* Move :ndn-cxx:`InMemoryStorage` and related classes to ``src/ims``
|
||||
* Rename ``digest.hpp`` to ``sha256.hpp`` to match the ``Sha256`` class declared within
|
||||
|
||||
Removed
|
||||
@@ -107,23 +102,23 @@ Removed
|
||||
|
||||
- Old security framework.
|
||||
|
||||
* ``v1::KeyChain``, use :ndn-cxx:`v2::KeyChain` instead
|
||||
* ``v1::KeyChain``; use :ndn-cxx:`KeyChain` instead.
|
||||
|
||||
* ``v1::Validator`` interface and ``ValidatorRegex`` implementation of this
|
||||
interface. ``ValidatorConfig``, ``ValidatorNull`` implementation refactored to be based on
|
||||
the new validation framework.
|
||||
|
||||
* ``v1::SecPublicInfo`` and its implementation (``SecPublicInfoSqlite``), ``SecTpm`` and its
|
||||
implementations (``SecTpmFile``, ``SecTpmOsx``). These classes are internal implementation
|
||||
and not intended to be used without ``v1::KeyChain``. :ndn-cxx:`v2::KeyChain` internally
|
||||
implementations (``SecTpmFile``, ``SecTpmOsx``). These classes are internal implementation
|
||||
and not intended to be used without ``v1::KeyChain``. The new :ndn-cxx:`KeyChain` internally
|
||||
uses the newly introduced :ndn-cxx:`Pib` and :ndn-cxx:`Tpm` interfaces with their
|
||||
corresponding implementations.
|
||||
|
||||
* ``v1::Certificate``, ``v1::IdentityCertificate``, ``v1::CertificateExtension``,
|
||||
``v1::CertificateSubjectDescription``, use :ndn-cxx:`v2::Certificate` and
|
||||
:ndn-cxx:`AdditionalDescription`
|
||||
``v1::CertificateSubjectDescription``; use the new :ndn-cxx:`Certificate` and
|
||||
:ndn-cxx:`AdditionalDescription` instead.
|
||||
|
||||
* ``v1::SecuredBag``, use ``v2::SafeBag`` instead
|
||||
* ``v1::SecuredBag``; use :ndn-cxx:`SafeBag` instead.
|
||||
|
||||
- Constant ``io::BASE_64``, use ``io::BASE64`` instead (:issue:`3741`)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- Initial support for `NDN packet format version 0.3
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
|
||||
* Recognize typed name components, allow typed name component in ``FinalBlockId``
|
||||
(:issue:`4526`)
|
||||
|
||||
@@ -13,7 +13,7 @@ New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- More support for `NDN packet format version 0.3
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
|
||||
- Allow applications to declare a default ``CanBePrefix`` setting (:issue:`4581`)
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ Release date: February 4, 2019
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- More support for `NDN packet format version
|
||||
0.3 <https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
- More support for `NDN packet format version 0.3
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
|
||||
* Stop using ``ChildSelector`` in ``NotificationSubscriber`` (:issue:`4664`)
|
||||
|
||||
@@ -18,41 +18,42 @@ New features
|
||||
- Scoped prefix registration, scoped Interest filter, and scoped pending Interest
|
||||
(:issue:`3919`, :issue:`4316`)
|
||||
|
||||
- Counters for satisfied and unsatisfied Interests in ``ForwarderStatus``
|
||||
- Counters for satisfied and unsatisfied Interests in :ndn-cxx:`ForwarderStatus`
|
||||
(:issue:`4720`)
|
||||
|
||||
- ``random::getRandomNumberEngine()`` in the public API
|
||||
- :ndn-cxx:`random::getRandomNumberEngine` in the public API
|
||||
|
||||
- ``MetadataObject`` class to encode/decode RDR-style metadata (:issue:`4707`)
|
||||
- :ndn-cxx:`MetadataObject` class to encode/decode RDR-style metadata (:issue:`4707`)
|
||||
|
||||
- ``SegmentFetcher::stop()`` (:issue:`4692`)
|
||||
- :ndn-cxx:`SegmentFetcher::stop` (:issue:`4692`)
|
||||
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Use openssl-based routines for the PKCS#8 decoding/decryption when exporting key from macOS
|
||||
Keychain (:issue:`4450`)
|
||||
|
||||
- Switch to AES-256 for private key encryption in PKCS #8 export
|
||||
|
||||
- Add exponential backoff in ``CertificateFetcherFromNetwork`` (:issue:`4718`, :issue:`4712`)
|
||||
- Use OpenSSL-based routines for PKCS #8 decoding/decryption when exporting keys from the
|
||||
macOS Keychain (:issue:`4450`)
|
||||
|
||||
- Forbid unrecognized TLVs before ``Name`` (:issue:`4667`)
|
||||
|
||||
- Stop accepting NonNegativeInteger as sequence number in NDNLP (:issue:`4598`)
|
||||
|
||||
- Add exponential backoff in :ndn-cxx:`CertificateFetcherFromNetwork` (:issue:`4718`,
|
||||
:issue:`4712`)
|
||||
|
||||
- Throw exception when loading an orphaned ``ValidationPolicyConfig`` (API violation)
|
||||
(:issue:`4758`)
|
||||
|
||||
- Forbid unrecognized TLVs before ``Name`` (:issue:`4667`)
|
||||
- Prevent memory pool size from becoming zero in :ndn-cxx:`InMemoryStorage` (:issue:`4769`)
|
||||
|
||||
- Prevent memory pool size from becoming zero in ``InMemoryStorage`` (:issue:`4769`)
|
||||
|
||||
- Clean up fetchers when destructing ``nfd::Controller`` (:issue:`4775`)
|
||||
- Clean up fetchers when destructing :ndn-cxx:`nfd::Controller` (:issue:`4775`)
|
||||
|
||||
- Fix ``SegmentFetcher`` undefined behavior caused by uncanceled pending interest
|
||||
(:issue:`4770`)
|
||||
|
||||
- Seed the PRNG with more entropy (:issue:`4808`)
|
||||
|
||||
- Stop accepting NonNegativeInteger as sequence number in NDNLP (:issue:`4598`)
|
||||
|
||||
- Backport C++17 ``std::any`` and ``std::variant`` as ``ndn::any`` and ``ndn::variant``
|
||||
|
||||
- Reimplement ``scheduler::EventId`` with ``CancelHandle`` (:issue:`4698`)
|
||||
@@ -60,7 +61,7 @@ Improvements and bug fixes
|
||||
Deprecated
|
||||
^^^^^^^^^^
|
||||
|
||||
- ``ndn-cxx/util/scheduler-scoped-event-id.hpp`` header as it is now sufficient to use
|
||||
- ``ndn-cxx/util/scheduler-scoped-event-id.hpp`` header, as it is now sufficient to use
|
||||
``ndn-cxx/util/scheduler.hpp`` header (:issue:`4698`)
|
||||
|
||||
- Implicit conversion from nullptr to ``scheduler::EventId`` (:issue:`4698`)
|
||||
|
||||
@@ -5,15 +5,15 @@ Release date: April 27, 2019
|
||||
|
||||
.. note::
|
||||
This is the last release to support the `NDN packet format version 0.2.1
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.2.1/>`__.
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.2.1/>`__.
|
||||
The next release will be able to encode and decode only the `v0.3 packet format
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__.
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.3/>`__.
|
||||
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- More support for `NDN packet format version 0.3
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.3/>`__ (:issue:`4527`)
|
||||
|
||||
* Support new naming conventions to encode/decode segment numbers, byte offsets, versions,
|
||||
timestamps, and sequence numbers based on typed name components (:issue:`4777`)
|
||||
@@ -23,7 +23,8 @@ New features
|
||||
- ``NDN_THROW`` macro to throw exceptions including file position and runtime context of the
|
||||
throw statement (:issue:`4834`)
|
||||
|
||||
- Ensure that a ``Block`` with TLV-TYPE zero is treated as invalid (:issue:`4726`, :issue:`4895`)
|
||||
- Ensure that a :ndn-cxx:`Block` with TLV-TYPE zero is treated as invalid (:issue:`4726`,
|
||||
:issue:`4895`)
|
||||
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -6,7 +6,7 @@ Release date: January 13, 2020
|
||||
**Breaking Change**
|
||||
|
||||
This release features support of only `NDN packet format version 0.3
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/>`__ (:issue:`4527`, :issue:`4567`,
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.3/>`__ (:issue:`4527`, :issue:`4567`,
|
||||
:issue:`4709`, :issue:`4913`). The library encodes and interprets Interest and Data
|
||||
packets only in 0.3 format; support for version 0.2 has been completely removed. In
|
||||
addition, the URI representation of Interest packets has been updated to follow the
|
||||
@@ -17,28 +17,29 @@ New features
|
||||
|
||||
- HMAC signing support (:issue:`3075`)
|
||||
|
||||
- Support for ``ParametersSha256DigestComponent`` in ``Name`` and ``Interest`` classes
|
||||
- Support for ``ParametersSha256DigestComponent`` in :ndn-cxx:`Name` and :ndn-cxx:`Interest`
|
||||
(:issue:`4658`)
|
||||
|
||||
- Encoding/decoding of ``HopLimit`` field in Interest (:issue:`4806`)
|
||||
- Encoding and decoding of ``HopLimit`` field in Interest (:issue:`4806`)
|
||||
|
||||
- PIT token (:issue:`4532`).
|
||||
- Support for encoding and decoding PIT token as NDNLPv2 field (:issue:`4532`).
|
||||
|
||||
PIT token is a hop-by-hop header field that identifies an Interest-Data exchange. The
|
||||
downstream node can assign an opaque token to an outgoing Interest, and the upstream node
|
||||
is expected to return the same token on the Data or Nack in reply to that Interest. This
|
||||
would allow the downstream node to accelerate its processing, especially in PIT lookup.
|
||||
|
||||
- ``io::loadBuffer`` and ``io::saveBuffer`` helper functions
|
||||
- :ndn-cxx:`io::loadBuffer` and :ndn-cxx:`io::saveBuffer` helper functions
|
||||
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Various improvements in the Linux implementation of ``NetworkMonitor`` class
|
||||
- Various improvements in the Linux implementation of :ndn-cxx:`NetworkMonitor`
|
||||
|
||||
- Rework of ``RttEstimator`` class:
|
||||
|
||||
* split into two classes: ``RttEstimator`` and ``RttEstimatorWithStats`` (:issue:`4887`)
|
||||
* split into two classes: :ndn-cxx:`RttEstimator` and :ndn-cxx:`RttEstimatorWithStats`
|
||||
(:issue:`4887`)
|
||||
* add a getter for the smoothed RTT value (:issue:`4892`)
|
||||
* switch to use ``time::nanoseconds`` (:issue:`4887`)
|
||||
|
||||
@@ -64,7 +65,7 @@ Removals
|
||||
|
||||
- Unused ``v2::PublicKey`` alias of ``transform::PublicKey``
|
||||
|
||||
- ``HmacFilter`` class, use SignerFilter and VerifierFilter instead
|
||||
- ``HmacFilter`` class, use :ndn-cxx:`SignerFilter` and :ndn-cxx:`VerifierFilter` instead
|
||||
|
||||
- Ill-defined equality operators for ``Interest``, ``MetaInfo``, ``Signature`` (:issue:`4569`)
|
||||
|
||||
|
||||
@@ -12,10 +12,11 @@ Additionally, this release drops support for CentOS 7 and adds support for CentO
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- Signed Interests according to Packet Specification v0.3 (:issue:`4804`)
|
||||
- `Signed Interests <https://docs.named-data.net/NDN-packet-spec/0.3/signed-interest.html>`__
|
||||
according to Packet Specification v0.3 (:issue:`4804`)
|
||||
|
||||
- Add "in-order" mode to ``SegmentFetcher`` and a corresponding signal that is emitted after each
|
||||
segment is received and validated in segment order. Segments that arrive out-of-order will be
|
||||
- Add "in-order" mode to :ndn-cxx:`SegmentFetcher` and a corresponding signal that is emitted after
|
||||
each segment is received and validated in segment order. Segments that arrive out-of-order will be
|
||||
buffered internally until all earlier segments have arrived and passed validation.
|
||||
|
||||
- Allow ``KeyLocator`` to either identify the full name of a certificate, an unversioned certificate
|
||||
@@ -34,7 +35,7 @@ Improvements and bug fixes
|
||||
|
||||
- Fix spurious error message from ``ndnsec-key-gen`` when ``key-id`` is specified (:issue:`5057`)
|
||||
|
||||
- Provide more fine-grained choices for ``name::UriFormat`` (:issue:`4777`)
|
||||
- Provide more fine-grained choices for :ndn-cxx:`name::UriFormat` (:issue:`4777`)
|
||||
|
||||
- Allow automatic log flushing to be disabled (:issue:`3668`)
|
||||
|
||||
@@ -49,7 +50,7 @@ Improvements and bug fixes
|
||||
|
||||
- Correctly handle non-existent identity in ``PibImpl::setDefaultIdentity``
|
||||
|
||||
- Fix incompatibility with ``time::toIsoString`` in Boost 1.73.0+
|
||||
- Fix incompatibility with Boost 1.73.0+ in :ndn-cxx:`time::toIsoString`
|
||||
|
||||
- Fix incompatibility with ``<version>`` header in C++20
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
ndn-cxx version 0.8.0
|
||||
---------------------
|
||||
|
||||
Release date: February 15, 2022
|
||||
|
||||
Important changes
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Flip default value of ``CanBePrefix`` to **false** (:issue:`4582`). This means that
|
||||
Interests created without explicitly specifying ``CanBePrefix`` option will be treated
|
||||
as Interests for exact Data name.
|
||||
|
||||
- Change default name component encoding convention to ``TYPED`` (:issue:`5044`)
|
||||
|
||||
- Update TLV-TYPE numbers to revision 3 of the `naming conventions`_
|
||||
|
||||
.. _naming conventions:
|
||||
https://named-data.net/publications/techreports/ndn-tr-22-3-ndn-memo-naming-conventions/
|
||||
|
||||
- Change TLV-TYPE number of ``IncomingFaceId`` field in NDNLP (:issue:`5185`)
|
||||
|
||||
- Update Interest ``ForwardingHint`` format (:issue:`5187`)
|
||||
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Support certificate name, versionless certificate name, and key name options for
|
||||
KeyLocator name in ``ValidatorConfig`` (:issue:`5142`)
|
||||
|
||||
- Generalize signature verification to allow ``digest-sha256``, effectively adding
|
||||
support of digest integrity verification in ``ValidatorConfig``
|
||||
|
||||
- Enforce ``sig-type`` check in ``ValidatorConfig`` (:issue:`4524`)
|
||||
|
||||
- Fix ``ValidatorConfig`` rule processing bug (:issue:`5145`)
|
||||
|
||||
- Prevent potential dereferencing of past-the-end iterator in ``Block::value()``
|
||||
|
||||
- Fail early in :ndn-cxx:`Block::blockFromValue` if TLV length is zero
|
||||
|
||||
- Refactor and cleanup of :ndn-cxx:`StatusDatasetContext`, including increase of maximum
|
||||
payload size of each produced segment to 8000 bytes
|
||||
|
||||
- Improve error reporting when loading a ``Certificate`` or ``SafeBag`` fails
|
||||
|
||||
- Add API to get the keyword name component for Metadata and Prefix Announcements
|
||||
|
||||
- Backport C++20 ``std::span`` and convert most APIs to use it
|
||||
|
||||
- Introduce ``time::{to,from}IsoExtendedString()`` utility functions
|
||||
|
||||
- Add support for OpenSSL 3.0. Note that because of the API changes, HMAC implementation
|
||||
does not currently work when compiled with OpenSSL 3.0+, use older version of OpenSSL
|
||||
when needed.
|
||||
|
||||
- Various build system and documentation extension and fixes
|
||||
|
||||
Deprecations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- ``Interest::setDefaultCanBePrefix()``
|
||||
|
||||
- ``Name::append(Block)`` overload, as it has confusing semantics (:issue:`5186`)
|
||||
|
||||
- ``ndnsec`` tool aliases: ``ndnsec-certgen``, ``ndnsec-dump-certificate``,
|
||||
``ndnsec-install-cert``, ``ndnsec-keygen``, ``ndnsec-ls-identity``
|
||||
|
||||
Removals
|
||||
^^^^^^^^
|
||||
|
||||
- Previously deprecated ``Signature`` class, its subclasses, and deprecated methods from
|
||||
``Data``, ``KeyChain``, ``SignatureInfo``, and ``SigningInfo``
|
||||
|
||||
- Redundant overloads of ``verifySignature()`` and ``verifyDigest()``
|
||||
|
||||
- Previously deprecated ``security/v2`` headers
|
||||
|
||||
- Previously deprecated ``CommandInterestSigner``
|
||||
|
||||
- Unused ``Transport::send()`` overload
|
||||
|
||||
- Remove HTTP download feature in ``ndnsec cert-install``, as it does not support HTTPS
|
||||
retrieval. The recommended way of installing certificates published over HTTP/HTTPS has
|
||||
been changed to use ``curl`` or ``wget`` (:issue:`4506`)
|
||||
@@ -0,0 +1,102 @@
|
||||
ndn-cxx version 0.8.1
|
||||
---------------------
|
||||
|
||||
Release date: December 31, 2022
|
||||
|
||||
.. note::
|
||||
This is the last release of ndn-cxx to support the C++14 standard.
|
||||
Future versions will require C++17 to build.
|
||||
|
||||
Important changes and new features
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- The minimum build requirements have been increased as follows:
|
||||
|
||||
- Either GCC >= 7.4.0 or Clang >= 6.0 is required on Linux
|
||||
- On macOS, Xcode 11.3 or later is recommended; older versions may still work but are not
|
||||
officially supported
|
||||
- Boost >= 1.65.1 and OpenSSL >= 1.1.1 are required on all platforms
|
||||
- Sphinx 4.0 or later is required to build the documentation
|
||||
|
||||
- CentOS Stream 9 is now officially supported; CentOS 8 has been dropped (:issue:`5181`)
|
||||
|
||||
- macOS 12 (Monterey) and 13 (Ventura) running on arm64 are now officially supported
|
||||
(:issue:`5135`)
|
||||
|
||||
- Add the initial version of a :ndn-cxx:`Segmenter` API that applications can use to simplify
|
||||
the process of chunking a large object into multiple signed Data packets (:issue:`5247`)
|
||||
|
||||
- Add ``KeyChain::makeCertificate()`` to simplify the creation of certificates
|
||||
|
||||
- Put the full certificate name in the ``KeyLocator`` field, instead of just the key name
|
||||
(:issue:`5112`)
|
||||
|
||||
- NFD management commands sent by :ndn-cxx:`nfd::Controller` now use the `new signed Interest
|
||||
format <https://docs.named-data.net/NDN-packet-spec/0.3/signed-interest.html>`__ (:issue:`4804`)
|
||||
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Several enhancements and cleanups in :ndn-cxx:`Name` and :ndn-cxx:`Component` to make
|
||||
the API more consistent and simpler to use (:issue:`5186`)
|
||||
|
||||
- Various improvements in the validation framework and policies
|
||||
|
||||
- Avoid redundant TLV decoding during Interest validation
|
||||
- Fix validation of signed Interests with malformed ``InterestSignatureInfo``
|
||||
- More accurate validation error codes are returned in several cases
|
||||
- Rename ``ValidationError::NO_SIGNATURE`` to ``MALFORMED_SIGNATURE``
|
||||
|
||||
- Optimize parsing of PIB and TPM locators in :ndn-cxx:`KeyChain`
|
||||
|
||||
- Major cleanup and modernization of PIB implementation
|
||||
|
||||
- Gracefully handle invalid or unsupported public keys stored in the PIB
|
||||
|
||||
- Fix OpenSSL 3.0 deprecation warnings in private key generation routines (:issue:`5154`)
|
||||
|
||||
- Change ``Certificate::getPublicKey()`` to return a ``span``
|
||||
|
||||
- Make :ndn-cxx:`Block` convertible to ``span<const uint8_t>``
|
||||
|
||||
- Avoid assertion failure in :ndn-cxx:`OBufferStream` under certain conditions (:issue:`5240`)
|
||||
|
||||
- Allow customizing the FaceId in :ndn-cxx:`DummyClientFace` (:issue:`5011`)
|
||||
|
||||
- Improve pretty-printing of certificates, e.g., in ``ndnsec list`` and ``ndnsec cert-dump``
|
||||
|
||||
- Relax restrictions on KeyId component type in ``ndnsec key-gen``
|
||||
|
||||
- Fix handling of ``--without-osx-keychain`` configure option (:issue:`3338`)
|
||||
|
||||
- Stop using the ``gold`` linker on Linux; prefer instead linking with ``lld`` if installed
|
||||
|
||||
- Update waf build system to version 2.0.24
|
||||
|
||||
- Various documentation improvements
|
||||
|
||||
Deprecations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- ``Name::append()`` overloads and :ndn-cxx:`Component` constructors that take a
|
||||
``const uint8_t*``. Use the ``span``-based overloads instead.
|
||||
|
||||
- ``Component::fromImplicitSha256Digest()`` and ``Component::fromParametersSha256Digest()``.
|
||||
Use one of the constructors directly instead.
|
||||
|
||||
Removals
|
||||
^^^^^^^^
|
||||
|
||||
- Obsolete TLV-TYPE definitions
|
||||
|
||||
- Many previously deprecated functions that take raw byte buffers as ``uint8_t*`` + ``size_t``,
|
||||
replaced by equivalent functions that take a ``span``. These include ``Data::setContent()``,
|
||||
``Interest::setApplicationParameters()``, ``Block::fromBuffer()``, ``verifySignature()``,
|
||||
``PublicKey::loadPkcs8()``, ``transform::bufferSource()``, ``random::generateSecureBytes()``,
|
||||
``printHex()``, ``toHex()``, and so on.
|
||||
|
||||
- Previously deprecated ``Name::append(Block)`` overload
|
||||
|
||||
- Previously deprecated ``Interest::setDefaultCanBePrefix()``
|
||||
|
||||
- ``ndn::any`` and related functionality
|
||||
+55
-59
@@ -1,139 +1,135 @@
|
||||
All ndn-cxx Releases
|
||||
++++++++++++++++++++
|
||||
====================
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:reversed:
|
||||
|
||||
release-notes/release-notes-0.7.1
|
||||
release-notes/release-notes-0.7.0
|
||||
release-notes/release-notes-0.6.6
|
||||
release-notes/release-notes-0.6.5
|
||||
release-notes/release-notes-0.6.3
|
||||
release-notes/release-notes-0.6.2
|
||||
release-notes/release-notes-0.6.1
|
||||
release-notes/release-notes-0.6.0
|
||||
release-notes/release-notes-0.5.1
|
||||
release-notes/release-notes-0.5.0
|
||||
release-notes/release-notes-0.4.1
|
||||
release-notes/release-notes-0.4.0
|
||||
release-notes/release-notes-0.3.4
|
||||
release-notes/release-notes-0.3.3
|
||||
release-notes/release-notes-0.3.2
|
||||
release-notes/release-notes-0.3.1
|
||||
release-notes/release-notes-0.3.0
|
||||
release-notes/release-notes-0.2.0
|
||||
release-notes/release-notes-0.1.0
|
||||
release-notes/*
|
||||
|
||||
* **ndn-cxx version 0.8.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.8.1>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.8.1/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.8.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.8.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.8.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.8.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.8.0>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.8.0/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.8.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.8.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.8.0.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.7.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.7.1>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.7.1/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.7.1>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.7.1/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.7.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.7.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.7.1.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.7.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.7.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.7.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.7.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.7.0/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.7.0>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.7.0/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.7.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.7.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.7.0.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.7.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.7.0.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.6.6**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.6>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.6/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.6>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.6/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.6>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.6.6.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.6.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.6.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.6.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.6.5**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.5>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.5/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.5>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.5/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.5>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.6.5.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.5.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.5.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.5.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.6.4 was skipped**
|
||||
* **ndn-cxx version 0.6.4** was skipped
|
||||
|
||||
* **ndn-cxx version 0.6.3**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.3>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.3/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.3>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.3/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.3>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.6.3.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.3.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.3.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.3.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.6.2**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.2>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.2/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.2>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.2/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.2>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.6.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.2.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.2.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.6.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.1>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.1/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.1>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.1/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.6.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.1.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.6.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.6.0/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.6.0>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.6.0/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.6.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.6.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.6.0.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.6.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.0.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.5.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.5.1>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.5.1/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.5.1>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.5.1/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.5.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.5.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.5.1.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.5.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.5.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.5.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.5.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.5.0/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.5.0>`, `Documentation <https://docs.named-data.net/ndn-cxx/0.5.0/>`__)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.5.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.5.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.5.0.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.5.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.5.0.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.4.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.1>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.4.1/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.1>`)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.4.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.4.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.4.1.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.4.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.4.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.4.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.4.0/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.4.0>`)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.4.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.4.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.4.0.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.4.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.4.0.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.3.4**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.4>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.3.4/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.4>`)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.3.4>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.3.4.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.3.4.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.3.4.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.3.4.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.3.3**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.3>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.3.3/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.3>`)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.3.3>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.3.3.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.3.3.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.3.3.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.3.3.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.3.2**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.2>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.3.2/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.2>`)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.3.2>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.3.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.3.2.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.3.2.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.3.2.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.3.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.1>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.3.1/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.1>`)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.3.1>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.3.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.3.1.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.3.1.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.3.1.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.3.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.3.0/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.3.0>`)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.3.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.3.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.3.0.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.3.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.3.0.tar.bz2.sha256>`__)
|
||||
|
||||
* **ndn-cxx version 0.2.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.2.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.2.0/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.2.0>`)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.2.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.2.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.2.0.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.2.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.2.0.tar.bz2.sha256>`__)
|
||||
|
||||
- ndn-cxx version 0.2.0-rc1
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.2.0-rc1>`__
|
||||
@@ -142,10 +138,10 @@ All ndn-cxx Releases
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.2.0-rc2>`__
|
||||
|
||||
* **ndn-cxx version 0.1.0**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.1.0>`, `Documentation <https://named-data.net/doc/ndn-cxx/0.1.0/>`__)
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.1.0>`)
|
||||
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.1.0>`__,
|
||||
`src (tarball) <https://named-data.net/downloads/nfd-0.1.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/nfd-0.1.0.tar.bz2.sha256>`__)
|
||||
`src (tarball) <https://named-data.net/downloads/ndn-cxx-0.1.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.1.0.tar.bz2.sha256>`__)
|
||||
|
||||
- ndn-cxx version 0.1.0-rc1
|
||||
`src (git) <https://github.com/named-data/ndn-cxx/releases/tag/ndn-cxx-0.1.0-rc1>`__
|
||||
+1
-3
@@ -4,7 +4,5 @@ Specifications
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
specs/signed-interest
|
||||
specs/certificate-format
|
||||
specs/safe-bag
|
||||
specs/validation-error-code
|
||||
specs/signed-interest
|
||||
@@ -1,200 +0,0 @@
|
||||
.. _NDN Certificate Format Version 2.0:
|
||||
|
||||
NDN Certificate Format Version 2.0
|
||||
==================================
|
||||
|
||||
Since signature verification is a common operation in NDN applications, it is
|
||||
important to define a common certificate format to standardize the public key
|
||||
authentication procedure. As every NDN data packet is signed, a data packet
|
||||
that carries a public key as content is conceptually a certificate. However,
|
||||
the specification of a data packet is not sufficient to be the specification of
|
||||
a common certificate format, as it requires additional components. For example,
|
||||
a certificate may follow a specific naming convention and may need to include
|
||||
validity period, revocation information, etc. This specification defines
|
||||
naming and structure of the NDN certificates and is complementary to NDN packet
|
||||
specification.
|
||||
|
||||
::
|
||||
|
||||
Overview of NDN certificate format
|
||||
+--------------------------+
|
||||
| Name |
|
||||
+--------------------------+
|
||||
| MetaInfo |
|
||||
|+------------------------+|
|
||||
|| ContentType: KEY(2) ||
|
||||
|+------------------------+|
|
||||
|+------------------------+|
|
||||
|| FreshnessPeriod: >~ 1h ||
|
||||
|+------------------------+|
|
||||
+--------------------------+
|
||||
| Content |
|
||||
|+------------------------+|
|
||||
|| Public Key ||
|
||||
|+------------------------+|
|
||||
+--------------------------+
|
||||
| SignatureInfo |
|
||||
|+------------------------+|
|
||||
|| SignatureType: ... ||
|
||||
|| KeyLocator: ... ||
|
||||
|| ValidityPeriod: ... ||
|
||||
|| ... ||
|
||||
|+------------------------+|
|
||||
+--------------------------+
|
||||
| SignatureValue |
|
||||
+--------------------------+
|
||||
|
||||
.. code-block:: abnf
|
||||
|
||||
CertificateV2 = DATA-TYPE TLV-LENGTH
|
||||
Name ; /<NameSpace>/KEY/[KeyId]/[IssuerId]/[Version]
|
||||
MetaInfo ; ContentType == KEY, FreshnessPeriod required
|
||||
Content ; X509PublicKey
|
||||
CertificateV2SignatureInfo
|
||||
SignatureValue
|
||||
|
||||
CertificateV2SignatureInfo = SIGNATURE-INFO-TYPE TLV-LENGTH
|
||||
SignatureType
|
||||
KeyLocator
|
||||
ValidityPeriod
|
||||
*CertificateV2Extension
|
||||
|
||||
|
||||
Name
|
||||
----
|
||||
|
||||
The name of a certificate consists of five parts as shown below::
|
||||
|
||||
/<SubjectName>/KEY/[KeyId]/[IssuerId]/[Version]
|
||||
|
||||
A certificate name starts with the subject to which a public key is bound. The following parts
|
||||
include the keyword ``KEY`` component, KeyId, IssuerId, and version components.
|
||||
|
||||
``KeyId`` is an opaque name component to identify an instance of the public key for the
|
||||
certificate namespace. The value of `Key ID` is controlled by the namespace owner and can be
|
||||
an 8-byte random number, SHA-256 digest of the public key, timestamp, or a simple numerical
|
||||
identifier.
|
||||
|
||||
``Issuer Id`` is an opaque name component to identify issuer of the certificate. The value is
|
||||
controlled by the certificate issuer and, similar to KeyId, can be an 8-byte random number,
|
||||
SHA-256 digest of the issuer's public key, or a simple numerical identifier.
|
||||
|
||||
For example::
|
||||
|
||||
/edu/ucla/cs/yingdi/KEY/%03%CD...%F1/%9F%D3...%B7/%FD%d2...%8E
|
||||
\_________________/ \___________/ \___________/\___________/
|
||||
Certificate Namespace Key Id Issuer Id Version
|
||||
(Identity)
|
||||
|
||||
MetaInfo
|
||||
--------
|
||||
|
||||
The ``ContentType`` of certificate is set to ``KEY`` (2).
|
||||
|
||||
The ``FreshnessPeriod`` of certificate must be explicitly specified. The
|
||||
recommended value is 1 hour (3,600,000 milliseconds).
|
||||
|
||||
Content
|
||||
-------
|
||||
|
||||
By default, the content of a certificate is the public key encoded in
|
||||
`X509PublicKey <https://tools.ietf.org/html/rfc5280#section-4.1.2.7>`__ format.
|
||||
|
||||
SignatureInfo
|
||||
-------------
|
||||
|
||||
The SignatureInfo block of a certificate is required to include the ``ValidityPeriod`` field.
|
||||
``ValidityPeriod`` includes two sub TLV fields: ``NotBefore`` and ``NotAfter``, which carry two
|
||||
UTC timestamps in ISO 8601 compact format (``yyyymmddTHHMMSS``, e.g., "20020131T235959").
|
||||
``NotBefore`` indicates when the certificate takes effect while ``NotAfter`` indicates when the
|
||||
certificate expires.
|
||||
|
||||
.. note::
|
||||
Using ISO style string is the convention of specifying the validity period of certificate,
|
||||
which has been adopted by many certificate systems, such as X.509, PGP, and DNSSEC.
|
||||
|
||||
.. code-block:: abnf
|
||||
|
||||
ValidityPeriod = VALIDITY-PERIOD-TYPE TLV-LENGTH
|
||||
NotBefore
|
||||
NotAfter
|
||||
|
||||
NotBefore = NOT-BEFORE-TYPE TLV-LENGTH 8DIGIT "T" 6DIGIT
|
||||
|
||||
NotAfter = NOT-AFTER-TYPE TLV-LENGTH 8DIGIT "T" 6DIGIT
|
||||
|
||||
For each TLV, the TLV-TYPE codes are assigned as below:
|
||||
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
| TLV-TYPE | Assigned code | Assigned code |
|
||||
| | (decimal) | (hexadecimal) |
|
||||
+=============================================+===================+================+
|
||||
| ValidityPeriod | 253 | 0xFD |
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
| NotBefore | 254 | 0xFE |
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
| NotAfter | 255 | 0xFF |
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
|
||||
Extensions
|
||||
~~~~~~~~~~
|
||||
|
||||
A certificate may optionally carry some extensions in SignatureInfo. An extension
|
||||
could be either critical or non-critical depends on the TLV-TYPE code convention. A
|
||||
critical extension implies that if a validator cannot recognize or parse the
|
||||
extension, the validator must reject the certificate. A non-critical extension
|
||||
implies that if a validator cannot recognize or cannot parse the extension, the
|
||||
validator may ignore the extension.
|
||||
|
||||
The TLV-TYPE code range [256, 512) is reserved for extensions. The last bit of a
|
||||
TLV-TYPE code indicates whether the extension is critical or not: ``1`` for critical
|
||||
while ``0`` for non-critical. If an extension could be either critical or
|
||||
non-critical, the extension should be allocated with two TLV-TYPE codes which only
|
||||
differ at the last bit.
|
||||
|
||||
Extensions
|
||||
----------
|
||||
|
||||
We list currently defined extensions:
|
||||
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
| TLV-TYPE | Assigned number | Assigned number|
|
||||
| | (decimal) | (hexadecimal) |
|
||||
+=============================================+===================+================+
|
||||
| AdditionalDescription (non-critical) | 258 | 0x0102 |
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
|
||||
AdditionalDescription
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``AdditionalDescription`` is a non-critical extension that provides additional
|
||||
information about the certificate. The information is expressed as a set of
|
||||
key-value pairs. Both key and value are UTF-8 strings, e.g.,
|
||||
``("Organization", "UCLA")``. The issuer of a certificate can specify arbitrary
|
||||
key-value pair to provide additional description about the certificate.
|
||||
|
||||
.. code-block:: abnf
|
||||
|
||||
CertificateV2Extension = AdditionalDescription
|
||||
|
||||
AdditionalDescription = ADDITIONAL-DESCRIPTION-TYPE TLV-LENGTH
|
||||
1*DescriptionEntry
|
||||
|
||||
DescriptionEntry = DESCRIPTION-ENTRY-TYPE TLV-LENGTH
|
||||
DescriptionKey
|
||||
DescriptionValue
|
||||
|
||||
DescriptionKey = DESCRIPTION-KEY-TYPE TLV-LENGTH 1*OCTET
|
||||
|
||||
DescriptionValue = DESCRIPTION-VALUE-TYPE TLV-LENGTH 1*OCTET
|
||||
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
| TLV-TYPE | Assigned number | Assigned number|
|
||||
| | (decimal) | (hexadecimal) |
|
||||
+=============================================+===================+================+
|
||||
| DescriptionEntry | 512 | 0x0200 |
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
| DescriptionKey | 513 | 0x0201 |
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
| DescriptionValue | 514 | 0x0202 |
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
+19
-20
@@ -1,30 +1,29 @@
|
||||
SafeBag Format for Exported Credentials
|
||||
=======================================
|
||||
|
||||
Sometimes, one may need to export credentials (e.g., certificate and private key) from
|
||||
one machine, and import them into another machine. This requires a secured container for
|
||||
sensitive information. We define **SafeBag**, which contains both an NDN certificate
|
||||
(:doc:`version 2.0 <certificate-format>`) and the corresponding private
|
||||
key, which is encrypted in `PKCS #8 format <https://tools.ietf.org/html/rfc5208>`_.
|
||||
Sometimes it may be necessary to export an identity's credentials (i.e., private key and associated
|
||||
certificate) from one machine and import them into another. This requires a secure container to
|
||||
carry the sensitive information. For this purpose, we define the **SafeBag** format, which contains
|
||||
an `NDN certificate <https://docs.named-data.net/NDN-packet-spec/0.3/certificate.html>`__ and the
|
||||
corresponding private key in encrypted form. The private key is formatted as a DER-encoded
|
||||
:rfc:`EncryptedPrivateKeyInfo <5208#section-6>` structure as described in PKCS #8.
|
||||
|
||||
The format of **SafeBag** is defined as:
|
||||
The TLV encoding of ``SafeBag`` is defined as follows:
|
||||
|
||||
.. code-block:: abnf
|
||||
|
||||
SafeBag = SAFE-BAG-TYPE TLV-LENGTH
|
||||
CertificateV2
|
||||
EncryptedKeyBag
|
||||
Certificate
|
||||
EncryptedKey
|
||||
|
||||
EncryptedKeyBag = ENCRYPTED-KEY-BAG-TYPE TLV-LENGTH
|
||||
*OCTET ; private key encrypted in PKCS #8 format
|
||||
EncryptedKey = ENCRYPTED-KEY-TYPE TLV-LENGTH
|
||||
*OCTET ; PKCS #8 EncryptedPrivateKeyInfo
|
||||
|
||||
All TLV-TYPE numbers are application specific:
|
||||
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
| TLV-TYPE | Assigned number | Assigned number|
|
||||
| | (decimal) | (hexadecimal) |
|
||||
+=============================================+===================+================+
|
||||
| SafeBag | 128 | 0x80 |
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
| EncryptedKeyBag | 129 | 0x81 |
|
||||
+---------------------------------------------+-------------------+----------------+
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
| Type | Assigned number | Assigned number |
|
||||
| | (decimal) | (hexadecimal) |
|
||||
+=============================================+==================+=================+
|
||||
| SafeBag | 128 | 0x80 |
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
| EncryptedKey | 129 | 0x81 |
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
@@ -1,12 +1,10 @@
|
||||
.. _Signed Interest:
|
||||
|
||||
Signed Interest Version 0.2 (DEPRECATED)
|
||||
========================================
|
||||
|
||||
.. warning::
|
||||
This document describes a deprecated format for signed Interest packets. The current format can
|
||||
be found in the
|
||||
`NDN Packet Specification <https://named-data.net/doc/NDN-packet-spec/current/signed-interest.html>`__.
|
||||
`NDN Packet Specification <https://docs.named-data.net/NDN-packet-spec/current/signed-interest.html>`__.
|
||||
|
||||
**Signed Interest** is a mechanism to issue an authenticated interest.
|
||||
|
||||
@@ -54,21 +52,21 @@ Timestamp component (n-3 *th*)
|
||||
|
||||
The value of the n-3 *th* component is the interest's timestamp (in terms of millisecond offset
|
||||
from UTC 1970-01-01 00:00:00) encoded as
|
||||
`NonNegativeInteger <https://named-data.net/doc/NDN-packet-spec/0.2.1/tlv.html#non-negative-integer-encoding>`__.
|
||||
`NonNegativeInteger <https://docs.named-data.net/NDN-packet-spec/0.2.1/tlv.html#non-negative-integer-encoding>`__.
|
||||
The timestamp may be used to protect against replay attack.
|
||||
|
||||
Nonce component (n-2 *th*)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The value of the n-2 *th* component is random value (encoded as
|
||||
`NonNegativeInteger <https://named-data.net/doc/NDN-packet-spec/0.2.1/tlv.html#non-negative-integer-encoding>`__)
|
||||
`NonNegativeInteger <https://docs.named-data.net/NDN-packet-spec/0.2.1/tlv.html#non-negative-integer-encoding>`__)
|
||||
that adds additional assurances that the interest will be unique.
|
||||
|
||||
SignatureInfo component (n-1 *th*)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The value of the n-1 *th* component is actually a
|
||||
`SignatureInfo <https://named-data.net/doc/NDN-packet-spec/0.2.1/signature.html>`__ TLV.
|
||||
`SignatureInfo <https://docs.named-data.net/NDN-packet-spec/0.2.1/signature.html>`__ TLV.
|
||||
|
||||
::
|
||||
|
||||
@@ -86,7 +84,7 @@ SignatureValue component (n *th*)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The value of the n *th* component is actually a
|
||||
`SignatureValue <https://named-data.net/doc/NDN-packet-spec/0.2.1/signature.html>`__ TLV.
|
||||
`SignatureValue <https://docs.named-data.net/NDN-packet-spec/0.2.1/signature.html>`__ TLV.
|
||||
|
||||
::
|
||||
|
||||
@@ -111,7 +109,7 @@ be signed, it will be treated as invalid in the following three cases:
|
||||
missing or cannot be parsed correctly;
|
||||
- the key is not trusted for signing the Interest;
|
||||
- the signature cannot be verified with the public key pointed by the
|
||||
`KeyLocator <https://named-data.net/doc/NDN-packet-spec/0.2.1/signature.html#keylocator>`__ in
|
||||
`KeyLocator <https://docs.named-data.net/NDN-packet-spec/0.2.1/signature.html#keylocator>`__ in
|
||||
SignatureInfo.
|
||||
|
||||
Recipients of a signed interest may further check the timestamp and the uniqueness of the
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
Validation Error Code
|
||||
=====================
|
||||
|
||||
The following table defines a list of known codes and their description, which can be returned from the :ndn-cxx:`v2::Validator` interface.
|
||||
Other error codes can be returned by validator implementations outside ndn-cxx codebase.
|
||||
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
| Error code | Short ID | Description |
|
||||
+============+==========================+=====================================================+
|
||||
| 0 | NO_ERROR | No error |
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
| 1 | INVALID_SIGNATURE | Invalid signature |
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
| 2 | NO_SIGNATURE | Missing signature |
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
| 3 | CANNOT_RETRIEVE_CERT | Cannot retrieve certificate |
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
| 4 | EXPIRED_CERT | Certificate expired |
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
| 5 | LOOP_DETECTED | Loop detected in certification chain |
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
| 6 | MALFORMED_CERT | Malformed certificate |
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
| 7 | EXCEEDED_DEPTH_LIMIT | Exceeded validation depth limit |
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
| 8 | INVALID_KEY_LOCATOR | Key locator violates validation policy |
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
| .. | ... | ... |
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
| 255 | IMPLEMENTATION_ERROR | Internal implementation error |
|
||||
+------------+--------------------------+-----------------------------------------------------+
|
||||
|
||||
Specialized validator implementations can use error codes >= 256 to indicate a specialized error.
|
||||
@@ -199,31 +199,38 @@ checkers:
|
||||
Customized Checker
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The customized checker requires two properties: **sig-type**, **key-locator**. Both must
|
||||
appear exactly once and are related to the ``SignatureInfo`` of a packet.
|
||||
The customized checker can include optional **sig-type** property, which specifies the acceptable signature
|
||||
type. If not specified, the checker will only accept ECDSA signature. Possible values for **sig-type** are:
|
||||
|
||||
- **ecdsa-sha256**: ECDSA signature required (default if **sig-type** not specified)
|
||||
- **rsa-sha256**: RSA signature required
|
||||
- **sha256** (not recommended, as it is not a real signature): SHA256 digest is required
|
||||
|
||||
If sig-type is **rsa-sha256** or **ecdsa-sha256**, the customized checker requires
|
||||
**key-locator** property. If sig-type is **sha256**, **key-locator** property can be
|
||||
specified, but is optional.
|
||||
|
||||
::
|
||||
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type ...
|
||||
sig-type rsa-sha256
|
||||
key-locator
|
||||
{
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
The property **sig-type** specifies the acceptable signature type and can be
|
||||
**rsa-sha256**, **ecdsa-sha256** (strong signature types), or **sha256** (weak signature
|
||||
type). If sig-type is sha256, **key-locator** is ignored, and the validator will simply
|
||||
calculate the digest of a packet and compare it with the one in ``SignatureValue``. If
|
||||
sig-type is rsa-sha256 or ecdsa-sha256, you have to further customize the checker with
|
||||
**key-locator**.
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type sha256
|
||||
}
|
||||
|
||||
The property **key-locator** specifies the conditions on ``KeyLocator``. If the
|
||||
**key-locator** property is specified, it requires the existence of the ``KeyLocator``
|
||||
field in ``SignatureInfo``. **key-locator** property only supports one type: **name**:
|
||||
The **key-locator** property is a nested configuration property that can appear exactly once
|
||||
and specifies conditions on ``KeyLocator``. It requires **type** property that currently
|
||||
supports only one value: **name**.
|
||||
|
||||
::
|
||||
|
||||
@@ -233,9 +240,9 @@ field in ``SignatureInfo``. **key-locator** property only supports one type: **
|
||||
...
|
||||
}
|
||||
|
||||
This key-locator property specifies the conditions on the certificate name of the signing
|
||||
key. Since the conditions are about name, they can be specified in the same way as the
|
||||
name filter. For example, a checker can be:
|
||||
``KeyLocator`` conditions can be specified in the same way as the name filter. For example, a
|
||||
checker that requires ``SignatureSha256WithRsa`` signature type with ``KeyLocator`` to be exactly
|
||||
``/ndn/edu/ucla/yingdi/KEY/1234`` can be written as follows:
|
||||
|
||||
::
|
||||
|
||||
@@ -251,13 +258,27 @@ name filter. For example, a checker can be:
|
||||
}
|
||||
}
|
||||
|
||||
This checker property requires that the packet must have a ``rsa-sha256`` signature that
|
||||
can be verified with ``/ndn/edu/ucla/yingdi/KEY/1234`` key.
|
||||
Similarly, a checker that requires ``SignatureSha256WithEcdsa`` signature with ``KeyLocator``
|
||||
that follows a regular expression pattern ``<ndn><>*<KEY><>{1,3}`` can be written as follows:
|
||||
|
||||
Besides the two ways to express conditions on the ``KeyLocator`` name (name and regex),
|
||||
you can further constrain the ``KeyLocator`` name using the information extracted from the
|
||||
packet name. This third type of condition is expressed via a property
|
||||
**hyper-relation**. The **hyper-relation** property consists of three parts:
|
||||
::
|
||||
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type ecdsa-sha256
|
||||
key-locator
|
||||
{
|
||||
type name
|
||||
regex <ndn><>*<KEY><>{1,3}
|
||||
relation equal
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
In addition, ``KeyLocator`` can be further constrained using information extracted from the
|
||||
packet name using the **hyper-relation** property.
|
||||
The **hyper-relation** property consists of three parts:
|
||||
|
||||
- an NDN regular expression that extracts information from the packet name
|
||||
- an NDN regular expression that extracts information from the ``KeyLocator`` name
|
||||
@@ -277,7 +298,7 @@ For example, a checker:
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^(<>*)<KEY><>$
|
||||
k-regex ^(<>*)<KEY><>{1,3}$
|
||||
k-expand \\1
|
||||
h-relation is-prefix-of
|
||||
p-regex ^(<>*)$
|
||||
@@ -317,7 +338,7 @@ is equivalent to a customized checker:
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^(<>*)<KEY><>$
|
||||
k-regex ^(<>*)<KEY><>{1,3}$
|
||||
k-expand \\1
|
||||
h-relation is-prefix-of
|
||||
p-regex ^(<>*)$
|
||||
|
||||
@@ -4,12 +4,12 @@ NDN Regular Expression
|
||||
NDN regular expression is a kind of regular expression that can match NDN names. Matching is
|
||||
performed at two levels: the name level and the name component level.
|
||||
|
||||
A name component matcher, enclosed in ``<`` and ``>``, specifies the pattern of a name component. The
|
||||
component pattern is expressed using the `Modified ECMAScript Regular Expression Syntax
|
||||
A name component matcher, enclosed in ``<`` and ``>``, specifies the pattern of a name component.
|
||||
The component pattern is expressed using the `Modified ECMAScript Regular Expression Syntax
|
||||
<https://en.cppreference.com/w/cpp/regex/ecmascript>`_.
|
||||
For example, ``<ab*c>`` matches the 1st, 3rd, and 4th components of ``/ac/dc/abc/abbc``, but does
|
||||
not match the 2nd component. A special case is that ``<>`` denotes a wildcard matcher that can match
|
||||
**ANY** name component.
|
||||
not match the 2nd component. A special case is that ``<>`` denotes a wildcard matcher that can
|
||||
match **ANY** name component.
|
||||
|
||||
A component matcher can match only one name component. To match a name, you need to compose an NDN
|
||||
regular expression with zero or more name component matchers. For example, ``<ndn><edu><ucla>``
|
||||
@@ -31,8 +31,8 @@ name: ``/ndn/edu``.
|
||||
Repetition
|
||||
~~~~~~~~~~
|
||||
|
||||
A component matcher can be followed by a repeat quantifier to indicate how many times the preceding
|
||||
component may appear.
|
||||
A component matcher can be followed by a **repeat quantifier** to indicate how many times the
|
||||
preceding component may appear.
|
||||
|
||||
The ``*`` quantifier denotes "zero or more times". For example, ``^<A><B>*<C>$`` matches ``/A/C``,
|
||||
``/A/B/C``, ``/A/B/B/C``, and so on.
|
||||
@@ -43,44 +43,44 @@ The ``+`` quantifier denotes "one or more times". For example, ``^<A><B>+<C>$``
|
||||
The ``?`` quantifier denotes "zero or one time". For example, ``^<A><B>?<C>`` matches ``/A/C`` and
|
||||
``/A/B/C``, but does not match ``/A/B/B/C``.
|
||||
|
||||
A bounded quantifier specifies a minimum and maximum number of permitted matches: ``{n}`` denotes
|
||||
"exactly ``n`` times"; ``{n,}`` denotes "at least ``n`` times"; ``{,n}`` denotes "at most ``n``
|
||||
times"; ``{n, m}`` denotes "between ``n`` and ``m`` times (inclusive)". For example,
|
||||
``^<A><B>{2, 4}<C>$`` matches ``/A/B/B/C`` and ``/A/B/B/B/B/C``.
|
||||
A **bounded quantifier** specifies either a minimum or a maximum number of permitted matches, or
|
||||
both. ``{n}`` means "exactly ``n`` times"; ``{n,}`` means "at least ``n`` times"; ``{,n}`` means
|
||||
"at most ``n`` times"; ``{m,n}`` (with ``m ≤ n``) means "between ``m`` and ``n`` times (inclusive)".
|
||||
For example, ``^<A><B>{2,4}<C>$`` matches ``/A/B/B/C`` and ``/A/B/B/B/B/C``.
|
||||
|
||||
Note that the quantifiers are **greedy**, which means it will consume as many matched components as
|
||||
possible. NDN regular expressions currently do not support non-greedy repeat matching and possessive
|
||||
repeat matching. For example, for the name ``/A/B/C/C/C``, ``^<A><B><C>+$`` will match the entire
|
||||
name instead of only ``/A/B/C``.
|
||||
Note that the quantifiers are *greedy*, meaning that they will consume as many matching components
|
||||
as possible. For example, for the name ``/A/B/C/C/C``, ``^<A><B><C>+`` will match the entire name
|
||||
instead of only ``/A/B/C``. NDN regular expressions do not currently support non-greedy quantifiers
|
||||
and possessive quantifiers.
|
||||
|
||||
Sets
|
||||
~~~~
|
||||
|
||||
A name component set, denoted by a bracket expression starting with ``[`` and ending with ``]``,
|
||||
A **name component set**, denoted by a bracket expression starting with ``[`` and ending with ``]``,
|
||||
defines a set of name components. It matches any single name component that is a member of that set.
|
||||
|
||||
Unlike standard regular expressions, NDN regular expression only supports **Single Components Set**,
|
||||
Unlike standard regular expressions, NDN regular expressions support only single components sets,
|
||||
that is, you have to list all the set members one by one between the brackets. For example,
|
||||
``^[<ndn><localhost>]`` matches any names starting with either ``ndn"`` or ``localhost`` component.
|
||||
``^[<ndn><localhost>]`` matches any names starting with either ``ndn`` or ``localhost`` component.
|
||||
|
||||
When a name component set starts with a ``'^'``, the set becomes a **Negation Set**. It matches the
|
||||
When a name component set starts with a ``'^'``, the set becomes a **negation set**. It matches the
|
||||
complement of the contained name components. For example, ``^[^<ndn>]`` matches any non-empty name
|
||||
that does not start with ``ndn`` component.
|
||||
that does *not* start with ``/ndn``.
|
||||
|
||||
Some other types of sets, such as Range Set, will be supported later.
|
||||
Some other types of sets, such as range sets, will be supported later.
|
||||
|
||||
Note that component sets may be repeated in the same way as component matchers.
|
||||
|
||||
Sub-pattern and Back Reference
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A section beginning ``(`` and ending ``)`` acts as a marked sub-pattern. Whatever matched the
|
||||
A section beginning ``(`` and ending ``)`` acts as a **marked sub-pattern**. Whatever matched the
|
||||
sub-pattern is split out in a separate field by the matching algorithm. For example
|
||||
``^<A>(<>{2})<B>(<>)`` matches the name ``/A/C/D/B/E``, and the first sub-pattern captures ``C/D``.
|
||||
|
||||
Marked sub-patterns can be referred to by a back-reference ``\N``, which references one or more
|
||||
capturing groups. In the example above, a back reference ``\1\2`` extracts ``/C/D/E`` out of the
|
||||
name.
|
||||
Marked sub-patterns can be referred to by a **back-reference** of the form ``\N``, which references
|
||||
one or more capturing groups. In the example above, a back reference ``\1\2`` extracts ``/C/D/E``
|
||||
out of the name.
|
||||
|
||||
Marked sub-patterns can also be repeated. The regex engine does not permanently substitute
|
||||
back-references in a regular expression, but will use the last match saved into the back-reference.
|
||||
|
||||
+37
-24
@@ -1,22 +1,22 @@
|
||||
ndn-cxx examples
|
||||
================
|
||||
# ndn-cxx examples
|
||||
|
||||
By default, examples in `examples/` folder are not built. To enable them, use
|
||||
By default, the examples in `examples/` folder are not built. To enable them, use
|
||||
`--with-examples` configure option. For example:
|
||||
|
||||
./waf configure --with-examples
|
||||
./waf
|
||||
|
||||
There are two ways to add new examples, depending on their complexity:
|
||||
There are two ways to add new examples, depending on their complexity.
|
||||
|
||||
1. Examples with a single translation unit
|
||||
1. **Examples with a single translation unit**
|
||||
|
||||
For simple examples that have a single translation unit, the `.cpp` file can be directly put
|
||||
in `examples/` folder and it will be automatically compiled on the next run of `./waf`. Name
|
||||
of the compiled binary will be determined by the base name of the `.cpp` file. For example,
|
||||
`examples/foo.cpp` will be compiled into binary `foo` in `<build>/examples` folder:
|
||||
For simple examples that have a single translation unit, the `.cpp` file can be directly put
|
||||
in the `examples/` folder and it will be automatically compiled on the next run of `./waf`.
|
||||
The name of the compiled executable will be determined by the base name of the `.cpp` file.
|
||||
For instance, `examples/foo.cpp` will be compiled into an executable named `foo` inside the
|
||||
`build/examples` folder:
|
||||
|
||||
echo "int main() { return 0; }" > examples/foo.cpp
|
||||
echo 'int main() { return 0; }' > examples/foo.cpp
|
||||
./waf
|
||||
# ... Compiling examples/foo.cpp
|
||||
# ... Linking build/examples/foo
|
||||
@@ -24,25 +24,23 @@ There are two ways to add new examples, depending on their complexity:
|
||||
# To run the example
|
||||
./build/examples/foo
|
||||
|
||||
2. Examples with multiple translation units
|
||||
2. **Examples with multiple translation units**
|
||||
|
||||
For more complex examples that contain multiple translation units, one can use
|
||||
the following directory structure:
|
||||
For more complex examples that contain multiple translation units, one can use
|
||||
the following directory structure:
|
||||
|
||||
- Create a directory under `examples/` folder (e.g., `examples/bar`).
|
||||
The name of this directory will determine the name of the compiled binary
|
||||
(`<build>/examples/bar/bar`)
|
||||
- Create a directory under the `examples/` folder (e.g., `examples/bar`). The name of this
|
||||
directory will determine the name of the compiled executable (`build/examples/bar/bar`).
|
||||
- Place any number of translation units (e.g., `examples/bar/a.cpp`, `examples/bar/b.cpp`,
|
||||
...) in this directory. All `.cpp` files in this directory will be compiled and linked
|
||||
together to produce the binary executable of the example. One of the .cpp files must
|
||||
contain the `main()` function.
|
||||
|
||||
- Place any number of translation units (e.g., `examples/bar/a.cpp`, `examples/bar/b.cpp`,
|
||||
...) in this directory. All `.cpp` files in this directory will be compiled and linked
|
||||
together to produce the binary of the example. One of the .cpp files should contain
|
||||
the `main()` function.
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
mkdir examples/bar
|
||||
echo "int bar(); int main() { return bar(); }" > examples/bar/a.cpp
|
||||
echo "int bar() { return 10; } " > examples/bar/b.cpp
|
||||
echo 'int bar(); int main() { return bar(); }' > examples/bar/a.cpp
|
||||
echo 'int bar() { return 10; }' > examples/bar/b.cpp
|
||||
./waf
|
||||
# ... Compiling examples/bar/a.cpp
|
||||
# ... Compiling examples/bar/b.cpp
|
||||
@@ -50,3 +48,18 @@ There are two ways to add new examples, depending on their complexity:
|
||||
|
||||
# To run the example
|
||||
./build/examples/bar/bar
|
||||
|
||||
## Security configuration for example apps
|
||||
|
||||
In order for the ``consumer`` example app to be able to properly authenticate data packets
|
||||
created by the ``producer`` app, you must configure the following parameters.
|
||||
|
||||
1. Generate example trust anchor:
|
||||
|
||||
ndnsec key-gen /example
|
||||
ndnsec cert-dump -i /example > example-trust-anchor.cert
|
||||
|
||||
2. Create a key for the producer and sign it with the example trust anchor:
|
||||
|
||||
ndnsec key-gen /example/testApp
|
||||
ndnsec sign-req /example/testApp | ndnsec cert-gen -s /example -i example | ndnsec cert-install -
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -17,14 +17,12 @@
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*
|
||||
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
*/
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// Enclosing code in ndn simplifies coding (can also use `using namespace ndn`)
|
||||
@@ -35,12 +33,6 @@ namespace examples {
|
||||
class ConsumerWithTimer
|
||||
{
|
||||
public:
|
||||
ConsumerWithTimer()
|
||||
: m_face(m_ioService) // Create face with io_service object
|
||||
, m_scheduler(m_ioService)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
@@ -48,21 +40,20 @@ public:
|
||||
interestName.appendVersion();
|
||||
|
||||
Interest interest(interestName);
|
||||
interest.setCanBePrefix(false);
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setInterestLifetime(2_s);
|
||||
|
||||
std::cout << "Sending Interest " << interest << std::endl;
|
||||
m_face.expressInterest(interest,
|
||||
bind(&ConsumerWithTimer::onData, this, _1, _2),
|
||||
bind(&ConsumerWithTimer::onNack, this, _1, _2),
|
||||
bind(&ConsumerWithTimer::onTimeout, this, _1));
|
||||
std::bind(&ConsumerWithTimer::onData, this, _1, _2),
|
||||
std::bind(&ConsumerWithTimer::onNack, this, _1, _2),
|
||||
std::bind(&ConsumerWithTimer::onTimeout, this, _1));
|
||||
|
||||
// Schedule a new event
|
||||
m_scheduler.schedule(3_s, [this] { delayedInterest(); });
|
||||
|
||||
// m_ioService.run() will block until all events finished or m_ioService.stop() is called
|
||||
m_ioService.run();
|
||||
// m_ioCtx.run() will block until all events finished or m_ioCtx.stop() is called
|
||||
m_ioCtx.run();
|
||||
|
||||
// Alternatively, m_face.processEvents() can also be called.
|
||||
// processEvents will block until the requested data received or timeout occurs.
|
||||
@@ -98,22 +89,21 @@ private:
|
||||
interestName.appendVersion();
|
||||
|
||||
Interest interest(interestName);
|
||||
interest.setCanBePrefix(false);
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setInterestLifetime(2_s);
|
||||
|
||||
std::cout << "Sending Interest " << interest << std::endl;
|
||||
m_face.expressInterest(interest,
|
||||
bind(&ConsumerWithTimer::onData, this, _1, _2),
|
||||
bind(&ConsumerWithTimer::onNack, this, _1, _2),
|
||||
bind(&ConsumerWithTimer::onTimeout, this, _1));
|
||||
std::bind(&ConsumerWithTimer::onData, this, _1, _2),
|
||||
std::bind(&ConsumerWithTimer::onNack, this, _1, _2),
|
||||
std::bind(&ConsumerWithTimer::onTimeout, this, _1));
|
||||
}
|
||||
|
||||
private:
|
||||
// Explicitly create io_service object, which will be shared between Face and Scheduler
|
||||
boost::asio::io_service m_ioService;
|
||||
Face m_face;
|
||||
Scheduler m_scheduler;
|
||||
// Explicitly create io_context object, which will be shared between Face and Scheduler
|
||||
boost::asio::io_context m_ioCtx;
|
||||
Face m_face{m_ioCtx};
|
||||
Scheduler m_scheduler{m_ioCtx};
|
||||
};
|
||||
|
||||
} // namespace examples
|
||||
|
||||
+20
-8
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2022 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -17,11 +17,10 @@
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*
|
||||
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
*/
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/security/validator-config.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -33,6 +32,11 @@ namespace examples {
|
||||
class Consumer
|
||||
{
|
||||
public:
|
||||
Consumer()
|
||||
{
|
||||
m_validator.load("trust-schema.conf");
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
@@ -40,15 +44,14 @@ public:
|
||||
interestName.appendVersion();
|
||||
|
||||
Interest interest(interestName);
|
||||
interest.setCanBePrefix(false);
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setInterestLifetime(6_s); // The default is 4 seconds
|
||||
|
||||
std::cout << "Sending Interest " << interest << std::endl;
|
||||
m_face.expressInterest(interest,
|
||||
bind(&Consumer::onData, this, _1, _2),
|
||||
bind(&Consumer::onNack, this, _1, _2),
|
||||
bind(&Consumer::onTimeout, this, _1));
|
||||
std::bind(&Consumer::onData, this, _1, _2),
|
||||
std::bind(&Consumer::onNack, this, _1, _2),
|
||||
std::bind(&Consumer::onTimeout, this, _1));
|
||||
|
||||
// processEvents will block until the requested data is received or a timeout occurs
|
||||
m_face.processEvents();
|
||||
@@ -56,9 +59,17 @@ public:
|
||||
|
||||
private:
|
||||
void
|
||||
onData(const Interest&, const Data& data) const
|
||||
onData(const Interest&, const Data& data)
|
||||
{
|
||||
std::cout << "Received Data " << data << std::endl;
|
||||
|
||||
m_validator.validate(data,
|
||||
[] (const Data&) {
|
||||
std::cout << "Data conforms to trust schema" << std::endl;
|
||||
},
|
||||
[] (const Data&, const security::ValidationError& error) {
|
||||
std::cout << "Error authenticating data: " << error << std::endl;
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
@@ -75,6 +86,7 @@ private:
|
||||
|
||||
private:
|
||||
Face m_face;
|
||||
ValidatorConfig m_validator{m_face};
|
||||
};
|
||||
|
||||
} // namespace examples
|
||||
|
||||
+29
-12
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -17,8 +17,6 @@
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*
|
||||
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
*/
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
@@ -38,25 +36,43 @@ public:
|
||||
void
|
||||
run()
|
||||
{
|
||||
m_face.setInterestFilter("/example/testApp",
|
||||
bind(&Producer::onInterest, this, _1, _2),
|
||||
m_face.setInterestFilter("/example/testApp/randomData",
|
||||
std::bind(&Producer::onInterest, this, _2),
|
||||
nullptr, // RegisterPrefixSuccessCallback is optional
|
||||
bind(&Producer::onRegisterFailed, this, _1, _2));
|
||||
std::bind(&Producer::onRegisterFailed, this, _1, _2));
|
||||
|
||||
auto cert = m_keyChain.getPib().getDefaultIdentity().getDefaultKey().getDefaultCertificate();
|
||||
m_certServeHandle = m_face.setInterestFilter(security::extractIdentityFromCertName(cert.getName()),
|
||||
[this, cert] (auto&&...) {
|
||||
m_face.put(cert);
|
||||
},
|
||||
std::bind(&Producer::onRegisterFailed, this, _1, _2));
|
||||
m_face.processEvents();
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
onInterest(const InterestFilter&, const Interest& interest)
|
||||
onInterest(const Interest& interest)
|
||||
{
|
||||
std::cout << ">> I: " << interest << std::endl;
|
||||
|
||||
static const std::string content("Hello, world!");
|
||||
|
||||
// Create Data packet
|
||||
auto data = make_shared<Data>(interest.getName());
|
||||
auto data = std::make_shared<Data>();
|
||||
data->setName(interest.getName());
|
||||
data->setFreshnessPeriod(10_s);
|
||||
data->setContent(reinterpret_cast<const uint8_t*>(content.data()), content.size());
|
||||
data->setContent("Hello, world!");
|
||||
|
||||
// In order for the consumer application to be able to validate the packet, you need to setup
|
||||
// the following keys:
|
||||
// 1. Generate example trust anchor
|
||||
//
|
||||
// ndnsec key-gen /example
|
||||
// ndnsec cert-dump -i /example > example-trust-anchor.cert
|
||||
//
|
||||
// 2. Create a key for the producer and sign it with the example trust anchor
|
||||
//
|
||||
// ndnsec key-gen /example/testApp
|
||||
// ndnsec sign-req /example/testApp | ndnsec cert-gen -s /example -i example | ndnsec cert-install -
|
||||
|
||||
// Sign Data packet with default identity
|
||||
m_keyChain.sign(*data);
|
||||
@@ -74,13 +90,14 @@ private:
|
||||
onRegisterFailed(const Name& prefix, const std::string& reason)
|
||||
{
|
||||
std::cerr << "ERROR: Failed to register prefix '" << prefix
|
||||
<< "' with the local forwarder (" << reason << ")" << std::endl;
|
||||
<< "' with the local forwarder (" << reason << ")\n";
|
||||
m_face.shutdown();
|
||||
}
|
||||
|
||||
private:
|
||||
Face m_face;
|
||||
KeyChain m_keyChain;
|
||||
ScopedRegisteredPrefixHandle m_certServeHandle;
|
||||
};
|
||||
|
||||
} // namespace examples
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
rule
|
||||
{
|
||||
id "Example rule"
|
||||
for data
|
||||
filter
|
||||
{
|
||||
type name
|
||||
name /example/testApp
|
||||
relation is-prefix-of
|
||||
}
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type ecdsa-sha256
|
||||
key-locator
|
||||
{
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^(<>*)<KEY><><>?<>?$
|
||||
k-expand \\1
|
||||
h-relation is-prefix-of
|
||||
p-regex ^(<>*)<>*$
|
||||
p-expand \\1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trust-anchor
|
||||
{
|
||||
type file
|
||||
file-name "example-trust-anchor.cert"
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@ def build(bld):
|
||||
# List all .cpp files (whole example in one .cpp)
|
||||
for ex in bld.path.ant_glob('*.cpp'):
|
||||
name = ex.change_ext('').path_from(bld.path.get_bld())
|
||||
bld.program(name='example-%s' % name,
|
||||
bld.program(name=f'example-{name}',
|
||||
target=name,
|
||||
source=[ex],
|
||||
use='ndn-cxx',
|
||||
@@ -15,7 +15,7 @@ def build(bld):
|
||||
# List all directories (example can have multiple .cpp in the directory)
|
||||
for subdir in bld.path.ant_glob('*', dir=True, src=False):
|
||||
name = subdir.path_from(bld.path)
|
||||
bld.program(name='example-%s' % name,
|
||||
bld.program(name=f'example-{name}',
|
||||
target=name,
|
||||
source=subdir.ant_glob('**/*.cpp'),
|
||||
use='ndn-cxx',
|
||||
|
||||
+98
-43
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -20,18 +20,10 @@
|
||||
*/
|
||||
|
||||
#include "ndn-cxx/data.hpp"
|
||||
#include "ndn-cxx/signature.hpp"
|
||||
#include "ndn-cxx/util/sha256.hpp"
|
||||
|
||||
namespace ndn {
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Data>));
|
||||
BOOST_CONCEPT_ASSERT((WireEncodable<Data>));
|
||||
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Data>));
|
||||
BOOST_CONCEPT_ASSERT((WireDecodable<Data>));
|
||||
static_assert(std::is_base_of<tlv::Error, Data::Error>::value,
|
||||
"Data::Error must inherit from tlv::Error");
|
||||
|
||||
Data::Data(const Name& name)
|
||||
: m_name(name)
|
||||
{
|
||||
@@ -52,16 +44,31 @@ Data::wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly) const
|
||||
// [Content]
|
||||
// SignatureInfo
|
||||
// SignatureValue
|
||||
// [ServiceClass]
|
||||
// [TargetRate]
|
||||
// (elements are encoded in reverse order)
|
||||
|
||||
size_t totalLength = 0;
|
||||
|
||||
// TargetRate
|
||||
if (getTargetRate()) {
|
||||
uint64_t targetRate = *getTargetRate();
|
||||
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::TargetRate, targetRate);
|
||||
// totalLength += encoder.prependByteArrayBlock(tlv::TargetRate, reinterpret_cast<uint8_t*>(&targetRate), sizeof(targetRate));
|
||||
}
|
||||
// ServiceClass
|
||||
if (getServiceClass()) {
|
||||
uint8_t serviceClass = *getServiceClass();
|
||||
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::ServiceClass, serviceClass);
|
||||
// totalLength += encoder.prependByteArrayBlock(tlv::ServiceClass, reinterpret_cast<uint8_t*>(&serviceClass), sizeof(serviceClass));
|
||||
}
|
||||
|
||||
// SignatureValue
|
||||
if (!wantUnsignedPortionOnly) {
|
||||
if (!m_signatureInfo) {
|
||||
NDN_THROW(Error("Requested wire format, but Data has not been signed"));
|
||||
}
|
||||
totalLength += encoder.prependBlock(m_signatureValue);
|
||||
totalLength += prependBlock(encoder, m_signatureValue);
|
||||
}
|
||||
|
||||
// SignatureInfo
|
||||
@@ -69,7 +76,7 @@ Data::wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly) const
|
||||
|
||||
// Content
|
||||
if (hasContent()) {
|
||||
totalLength += encoder.prependBlock(m_content);
|
||||
totalLength += prependBlock(encoder, m_content);
|
||||
}
|
||||
|
||||
// MetaInfo
|
||||
@@ -92,10 +99,12 @@ template size_t
|
||||
Data::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, bool) const;
|
||||
|
||||
const Block&
|
||||
Data::wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const
|
||||
Data::wireEncode(EncodingBuffer& encoder, span<const uint8_t> signature) const
|
||||
{
|
||||
size_t totalLength = encoder.size();
|
||||
totalLength += encoder.appendBlock(signatureValue);
|
||||
totalLength += encoder.appendVarNumber(tlv::SignatureValue);
|
||||
totalLength += encoder.appendVarNumber(signature.size());
|
||||
totalLength += encoder.appendBytes(signature);
|
||||
|
||||
encoder.prependVarNumber(totalLength);
|
||||
encoder.prependVarNumber(tlv::Data);
|
||||
@@ -135,6 +144,8 @@ Data::wireDecode(const Block& wire)
|
||||
// [Content]
|
||||
// SignatureInfo
|
||||
// SignatureValue
|
||||
// [ServiceClass]
|
||||
// [TargetRate]
|
||||
|
||||
auto element = m_wire.elements_begin();
|
||||
if (element == m_wire.elements_end() || element->type() != tlv::Name) {
|
||||
@@ -183,6 +194,30 @@ Data::wireDecode(const Block& wire)
|
||||
lastElement = 5;
|
||||
break;
|
||||
}
|
||||
case tlv::ServiceClass: {
|
||||
if (lastElement >= 6) {
|
||||
break; // ServiceClass is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
if (element->value_size() != 1) {
|
||||
NDN_THROW(Error("ServiceClass element is malformed"));
|
||||
}
|
||||
m_serviceClass = *element->value();
|
||||
lastElement = 6;
|
||||
break;
|
||||
}
|
||||
case tlv::TargetRate: {
|
||||
if (lastElement >= 7) {
|
||||
break; // TargetRate is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
uint64_t targetRate = 0;
|
||||
if (element->value_size() != 8) {
|
||||
NDN_THROW(Error("TargetRate element is malformed"));
|
||||
}
|
||||
std::memcpy(&targetRate, element->value(), sizeof(targetRate));
|
||||
m_targetRate = targetRate;
|
||||
lastElement = 7;
|
||||
break;
|
||||
}
|
||||
default: { // unrecognized element
|
||||
// if the TLV-TYPE is critical, abort decoding
|
||||
if (tlv::isCriticalType(element->type())) {
|
||||
@@ -210,7 +245,7 @@ Data::getFullName() const
|
||||
NDN_THROW(Error("Cannot compute full name because Data has no wire encoding (not signed)"));
|
||||
}
|
||||
m_fullName = m_name;
|
||||
m_fullName.appendImplicitSha256Digest(util::Sha256::computeDigest(m_wire.wire(), m_wire.size()));
|
||||
m_fullName.appendImplicitSha256Digest(util::Sha256::computeDigest(m_wire));
|
||||
}
|
||||
|
||||
return m_fullName;
|
||||
@@ -260,13 +295,17 @@ Data::setContent(const Block& block)
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setContent(const uint8_t* value, size_t length)
|
||||
Data::setContent(span<const uint8_t> value)
|
||||
{
|
||||
if (value == nullptr && length != 0) {
|
||||
NDN_THROW(std::invalid_argument("Content buffer cannot be nullptr"));
|
||||
}
|
||||
m_content = makeBinaryBlock(tlv::Content, value);
|
||||
resetWire();
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_content = makeBinaryBlock(tlv::Content, value, length);
|
||||
Data&
|
||||
Data::setContent(std::string_view value)
|
||||
{
|
||||
m_content = makeStringBlock(tlv::Content, value);
|
||||
resetWire();
|
||||
return *this;
|
||||
}
|
||||
@@ -274,8 +313,8 @@ Data::setContent(const uint8_t* value, size_t length)
|
||||
Data&
|
||||
Data::setContent(ConstBufferPtr value)
|
||||
{
|
||||
if (value == nullptr) {
|
||||
NDN_THROW(std::invalid_argument("Content buffer cannot be nullptr"));
|
||||
if (!value) {
|
||||
NDN_THROW(std::invalid_argument("Content buffer cannot be null"));
|
||||
}
|
||||
|
||||
m_content = Block(tlv::Content, std::move(value));
|
||||
@@ -286,23 +325,10 @@ Data::setContent(ConstBufferPtr value)
|
||||
Data&
|
||||
Data::unsetContent()
|
||||
{
|
||||
m_content = {};
|
||||
resetWire();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Signature
|
||||
Data::getSignature() const
|
||||
{
|
||||
return Signature(m_signatureInfo, m_signatureValue);
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setSignature(const Signature& signature)
|
||||
{
|
||||
m_signatureInfo = signature.getSignatureInfo();
|
||||
m_signatureValue = signature.getValue();
|
||||
resetWire();
|
||||
if (m_content.isValid()) {
|
||||
m_content = {};
|
||||
resetWire();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -314,11 +340,19 @@ Data::setSignatureInfo(const SignatureInfo& info)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setSignatureValue(span<const uint8_t> value)
|
||||
{
|
||||
m_signatureValue = makeBinaryBlock(tlv::SignatureValue, value);
|
||||
resetWire();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setSignatureValue(ConstBufferPtr value)
|
||||
{
|
||||
if (value == nullptr) {
|
||||
NDN_THROW(std::invalid_argument("SignatureValue buffer cannot be nullptr"));
|
||||
if (!value) {
|
||||
NDN_THROW(std::invalid_argument("SignatureValue buffer cannot be null"));
|
||||
}
|
||||
|
||||
m_signatureValue = Block(tlv::SignatureValue, std::move(value));
|
||||
@@ -334,11 +368,31 @@ Data::extractSignedRanges() const
|
||||
|
||||
wireEncode();
|
||||
auto lastSignedIt = std::prev(m_wire.find(tlv::SignatureValue));
|
||||
bufs.emplace_back(m_wire.value(),
|
||||
std::distance(m_wire.value_begin(), lastSignedIt->end()));
|
||||
// Note: we assume that both iterators point to the same underlying buffer
|
||||
bufs.emplace_back(m_wire.value_begin(), lastSignedIt->end());
|
||||
|
||||
return bufs;
|
||||
}
|
||||
|
||||
const Data&
|
||||
Data::setServiceClass(std::optional<uint8_t> serviceClass) const
|
||||
{
|
||||
if (m_serviceClass != serviceClass) {
|
||||
m_serviceClass = serviceClass;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
const Data&
|
||||
Data::setTargetRate(std::optional<uint64_t> targetRate) const
|
||||
{
|
||||
if (m_targetRate != targetRate) {
|
||||
m_targetRate = targetRate;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setContentType(uint32_t type)
|
||||
{
|
||||
@@ -360,7 +414,7 @@ Data::setFreshnessPeriod(time::milliseconds freshnessPeriod)
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setFinalBlock(optional<name::Component> finalBlockId)
|
||||
Data::setFinalBlock(std::optional<name::Component> finalBlockId)
|
||||
{
|
||||
if (finalBlockId != m_metaInfo.getFinalBlock()) {
|
||||
m_metaInfo.setFinalBlock(std::move(finalBlockId));
|
||||
@@ -396,3 +450,4 @@ operator<<(std::ostream& os, const Data& data)
|
||||
}
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
+153
-99
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -31,10 +31,9 @@
|
||||
|
||||
namespace ndn {
|
||||
|
||||
class Signature;
|
||||
|
||||
/** @brief Represents a %Data packet.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/data.html
|
||||
/**
|
||||
* @brief Represents a %Data packet.
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/data.html
|
||||
*/
|
||||
class Data : public PacketBase, public std::enable_shared_from_this<Data>
|
||||
{
|
||||
@@ -62,49 +61,55 @@ public:
|
||||
explicit
|
||||
Data(const Block& wire);
|
||||
|
||||
/** @brief Prepend wire encoding to @p encoder
|
||||
* @param encoder EncodingEstimator or EncodingBuffer instance.
|
||||
* @param wantUnsignedPortionOnly If true, prepend only Name, MetaInfo, Content, and
|
||||
* SignatureInfo to @p encoder, but omit SignatureValue and the outermost TLV
|
||||
* Type and Length of the Data element. This is intended to be used with
|
||||
* wireEncode(EncodingBuffer&, const Block&) const.
|
||||
* @throw Error %Signature is not present and @p wantUnsignedPortionOnly is false.
|
||||
/**
|
||||
* @brief Prepend wire encoding to @p encoder.
|
||||
* @param encoder EncodingEstimator or EncodingBuffer instance.
|
||||
* @param wantUnsignedPortionOnly If true, prepend only Name, MetaInfo, Content, and
|
||||
* SignatureInfo to @p encoder, but omit SignatureValue and the outermost TLV
|
||||
* Type and Length of the %Data element. This is intended to be used with
|
||||
* wireEncode(EncodingBuffer&, span<const uint8_t>) const.
|
||||
* @throw Error Signature is not present and @p wantUnsignedPortionOnly is false.
|
||||
*/
|
||||
template<encoding::Tag TAG>
|
||||
size_t
|
||||
wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly = false) const;
|
||||
|
||||
/** @brief Finalize Data packet encoding with the specified SignatureValue
|
||||
* @param encoder EncodingBuffer containing Name, MetaInfo, Content, and SignatureInfo, but
|
||||
* without SignatureValue and the outermost Type-Length of the Data element.
|
||||
* @param signatureValue SignatureValue element.
|
||||
/**
|
||||
* @brief Finalize Data packet encoding with the specified signature.
|
||||
* @param encoder EncodingBuffer containing Name, MetaInfo, Content, and SignatureInfo, but
|
||||
* without SignatureValue and the outermost Type-Length of the %Data element.
|
||||
* @param signature Raw signature bytes, without TLV Type and Length; this will become the
|
||||
* TLV-VALUE of the SignatureValue element added to the packet.
|
||||
*
|
||||
* This method is intended to be used in concert with `wireEncode(encoder, true)`, e.g.:
|
||||
* @code
|
||||
* Data data;
|
||||
* ...
|
||||
* EncodingBuffer encoder;
|
||||
* data.wireEncode(encoder, true);
|
||||
* ...
|
||||
* Block signatureValue = <sign_over_unsigned_portion>(encoder.buf(), encoder.size());
|
||||
* data.wireEncode(encoder, signatureValue)
|
||||
* @endcode
|
||||
* This method is intended to be used in concert with `wireEncode(encoder, true)`, e.g.:
|
||||
* @code
|
||||
* Data data;
|
||||
* ...
|
||||
* EncodingBuffer encoder;
|
||||
* data.wireEncode(encoder, true);
|
||||
* ...
|
||||
* auto signature = create_signature_over_signed_portion(encoder.data(), encoder.size());
|
||||
* data.wireEncode(encoder, signature);
|
||||
* @endcode
|
||||
*/
|
||||
const Block&
|
||||
wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
|
||||
wireEncode(EncodingBuffer& encoder, span<const uint8_t> signature) const;
|
||||
|
||||
/** @brief Encode into a Block.
|
||||
* @pre Data must be signed.
|
||||
/**
|
||||
* @brief Encode into a Block.
|
||||
* @pre Data must be signed.
|
||||
*/
|
||||
const Block&
|
||||
wireEncode() const;
|
||||
|
||||
/** @brief Decode from @p wire.
|
||||
/**
|
||||
* @brief Decode from @p wire.
|
||||
*/
|
||||
void
|
||||
wireDecode(const Block& wire);
|
||||
|
||||
/** @brief Check if this instance has cached wire encoding.
|
||||
/**
|
||||
* @brief Check if this instance has cached wire encoding.
|
||||
*/
|
||||
bool
|
||||
hasWire() const noexcept
|
||||
@@ -112,15 +117,17 @@ public:
|
||||
return m_wire.hasWire();
|
||||
}
|
||||
|
||||
/** @brief Get full name including implicit digest
|
||||
* @pre hasWire() == true; i.e. wireEncode() must have been called
|
||||
* @throw Error Data has no wire encoding
|
||||
/**
|
||||
* @brief Get the full name (including implicit digest).
|
||||
* @pre hasWire() == true, i.e., wireEncode() must have been called.
|
||||
* @throw Error Data has no wire encoding
|
||||
*/
|
||||
const Name&
|
||||
getFullName() const;
|
||||
|
||||
public: // Data fields
|
||||
/** @brief Get name
|
||||
/**
|
||||
* @brief Get the %Data name.
|
||||
*/
|
||||
const Name&
|
||||
getName() const noexcept
|
||||
@@ -128,13 +135,15 @@ public: // Data fields
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/** @brief Set name
|
||||
* @return a reference to this Data, to allow chaining
|
||||
/**
|
||||
* @brief Set the %Data name.
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
*/
|
||||
Data&
|
||||
setName(const Name& name);
|
||||
|
||||
/** @brief Get MetaInfo
|
||||
/**
|
||||
* @brief Get the `MetaInfo` element.
|
||||
*/
|
||||
const MetaInfo&
|
||||
getMetaInfo() const noexcept
|
||||
@@ -142,14 +151,15 @@ public: // Data fields
|
||||
return m_metaInfo;
|
||||
}
|
||||
|
||||
/** @brief Set MetaInfo
|
||||
* @return a reference to this Data, to allow chaining
|
||||
/**
|
||||
* @brief Set the `MetaInfo` element.
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
*/
|
||||
Data&
|
||||
setMetaInfo(const MetaInfo& metaInfo);
|
||||
|
||||
/**
|
||||
* @brief Return whether this Data has a Content element
|
||||
* @brief Return whether this Data has a `Content` element.
|
||||
*/
|
||||
bool
|
||||
hasContent() const noexcept
|
||||
@@ -158,15 +168,17 @@ public: // Data fields
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the Content element
|
||||
* @brief Get the `Content` element.
|
||||
*
|
||||
* If the element is not present (hasContent() == false), an invalid Block will be returned.
|
||||
*
|
||||
* The value of the returned Content Block (if valid) can be accessed through
|
||||
* Block::value() / Block::value_size() or Block::value_begin() / Block::value_end().
|
||||
* - Block::value_bytes(), or
|
||||
* - Block::value() and Block::value_size(), or
|
||||
* - Block::value_begin() and Block::value_end().
|
||||
*
|
||||
* @sa hasContent()
|
||||
* @sa Block::blockFromValue(), Block::parse()
|
||||
* @sa Block::value_bytes(), Block::blockFromValue(), Block::parse()
|
||||
*/
|
||||
const Block&
|
||||
getContent() const noexcept
|
||||
@@ -175,9 +187,9 @@ public: // Data fields
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set Content from a Block
|
||||
* @brief Set `Content` from a Block.
|
||||
* @param block TLV block to be used as Content; must be valid
|
||||
* @return a reference to this Data, to allow chaining
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
*
|
||||
* If the block's TLV-TYPE is tlv::Content, it will be used directly as this Data's
|
||||
* Content element. Otherwise, the block will be nested into a Content element.
|
||||
@@ -186,46 +198,42 @@ public: // Data fields
|
||||
setContent(const Block& block);
|
||||
|
||||
/**
|
||||
* @brief Set Content by copying from a raw buffer
|
||||
* @param value buffer with the TLV-VALUE of the content; may be nullptr if @p length is zero
|
||||
* @param length size of the buffer
|
||||
* @return a reference to this Data, to allow chaining
|
||||
* @brief Set `Content` by copying from a contiguous sequence of bytes.
|
||||
* @param value buffer with the TLV-VALUE of the content
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
*/
|
||||
Data&
|
||||
setContent(const uint8_t* value, size_t length);
|
||||
setContent(span<const uint8_t> value);
|
||||
|
||||
/**
|
||||
* @brief Set Content from a shared buffer
|
||||
* @param value buffer with the TLV-VALUE of the content; must not be nullptr
|
||||
* @return a reference to this Data, to allow chaining
|
||||
* @brief Set `Content` by copying from a string.
|
||||
* @param value string with the TLV-VALUE of the content
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
*/
|
||||
Data&
|
||||
setContent(std::string_view value);
|
||||
|
||||
/**
|
||||
* @brief Set `Content` from a shared buffer.
|
||||
* @param value buffer with the TLV-VALUE of the content; must not be null
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
*/
|
||||
Data&
|
||||
setContent(ConstBufferPtr value);
|
||||
|
||||
Data&
|
||||
setContent(std::nullptr_t) = delete;
|
||||
|
||||
/**
|
||||
* @brief Remove the Content element
|
||||
* @return a reference to this Data, to allow chaining
|
||||
* @brief Remove the `Content` element.
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
* @post hasContent() == false
|
||||
*/
|
||||
Data&
|
||||
unsetContent();
|
||||
|
||||
/** @brief Get Signature
|
||||
* @deprecated Use getSignatureInfo and getSignatureValue
|
||||
*/
|
||||
[[deprecated("use getSignatureInfo and getSignatureValue")]]
|
||||
Signature
|
||||
getSignature() const;
|
||||
|
||||
/** @brief Set Signature
|
||||
* @deprecated Use setSignatureInfo and setSignatureValue
|
||||
* @return a reference to this Data, to allow chaining
|
||||
*/
|
||||
[[deprecated("use setSignatureInfo and setSignatureValue")]]
|
||||
Data&
|
||||
setSignature(const Signature& signature);
|
||||
|
||||
/** @brief Get SignatureInfo
|
||||
/**
|
||||
* @brief Get the `SignatureInfo` element.
|
||||
*/
|
||||
const SignatureInfo&
|
||||
getSignatureInfo() const noexcept
|
||||
@@ -233,19 +241,21 @@ public: // Data fields
|
||||
return m_signatureInfo;
|
||||
}
|
||||
|
||||
/** @brief Set SignatureInfo
|
||||
/**
|
||||
* @brief Set the `SignatureInfo` element.
|
||||
*
|
||||
* This is a low-level function that should not normally be called directly by applications.
|
||||
* Instead, provide a SignatureInfo to the SigningInfo object passed to KeyChain::sign().
|
||||
* This is a low-level function that should not normally be called directly by applications.
|
||||
* Instead, provide a SignatureInfo to the SigningInfo object passed to KeyChain::sign().
|
||||
*
|
||||
* @return a reference to this Data, to allow chaining
|
||||
* @warning SignatureInfo is overwritten when the packet is signed via KeyChain::sign().
|
||||
* @sa SigningInfo
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
* @warning SignatureInfo is overwritten when the packet is signed via KeyChain::sign().
|
||||
* @sa SigningInfo
|
||||
*/
|
||||
Data&
|
||||
setSignatureInfo(const SignatureInfo& info);
|
||||
|
||||
/** @brief Get SignatureValue
|
||||
/**
|
||||
* @brief Get the `SignatureValue` element.
|
||||
*/
|
||||
const Block&
|
||||
getSignatureValue() const noexcept
|
||||
@@ -253,25 +263,59 @@ public: // Data fields
|
||||
return m_signatureValue;
|
||||
}
|
||||
|
||||
/** @brief Set SignatureValue
|
||||
* @param value buffer containing the TLV-VALUE of the SignatureValue; must not be nullptr
|
||||
/**
|
||||
* @brief Set `SignatureValue` by copying from a contiguous sequence of bytes.
|
||||
* @param value buffer from which the TLV-VALUE of the SignatureValue will be copied
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
*
|
||||
* This is a low-level function that should not normally be called directly by applications.
|
||||
* Instead, use KeyChain::sign() to sign the packet.
|
||||
* This is a low-level function that should not normally be called directly by applications.
|
||||
* Instead, use KeyChain::sign() to sign the packet.
|
||||
*
|
||||
* @return a reference to this Data, to allow chaining
|
||||
* @warning SignatureValue is overwritten when the packet is signed via KeyChain::sign().
|
||||
* @warning SignatureValue is overwritten when the packet is signed via KeyChain::sign().
|
||||
*/
|
||||
Data&
|
||||
setSignatureValue(span<const uint8_t> value);
|
||||
|
||||
/**
|
||||
* @brief Set `SignatureValue` from a shared buffer.
|
||||
* @param value buffer containing the TLV-VALUE of the SignatureValue; must not be null
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
*
|
||||
* This is a low-level function that should not normally be called directly by applications.
|
||||
* Instead, use KeyChain::sign() to sign the packet.
|
||||
*
|
||||
* @warning SignatureValue is overwritten when the packet is signed via KeyChain::sign().
|
||||
*/
|
||||
Data&
|
||||
setSignatureValue(ConstBufferPtr value);
|
||||
|
||||
/** @brief Extract ranges of Data covered by the signature
|
||||
* @throw Error Data cannot be encoded or is missing ranges necessary for signing
|
||||
* @warning The returned pointers will be invalidated if wireDecode() or wireEncode() are called.
|
||||
Data&
|
||||
setSignatureValue(std::nullptr_t) = delete;
|
||||
|
||||
/**
|
||||
* @brief Extract ranges of Data covered by the signature.
|
||||
* @throw Error Data cannot be encoded or is missing ranges necessary for signing
|
||||
* @warning The returned pointers will be invalidated if wireDecode() or wireEncode() are called.
|
||||
*/
|
||||
InputBuffers
|
||||
[[nodiscard]] InputBuffers
|
||||
extractSignedRanges() const;
|
||||
|
||||
std::optional<uint8_t>
|
||||
getServiceClass() const noexcept
|
||||
{
|
||||
return m_serviceClass;
|
||||
}
|
||||
const Data&
|
||||
setServiceClass(std::optional<uint8_t> serviceClass) const;
|
||||
|
||||
std::optional<uint64_t>
|
||||
getTargetRate() const noexcept
|
||||
{
|
||||
return m_targetRate;
|
||||
}
|
||||
const Data&
|
||||
setTargetRate(std::optional<uint64_t> targetRate) const;
|
||||
|
||||
public: // MetaInfo fields
|
||||
uint32_t
|
||||
getContentType() const
|
||||
@@ -291,18 +335,19 @@ public: // MetaInfo fields
|
||||
Data&
|
||||
setFreshnessPeriod(time::milliseconds freshnessPeriod);
|
||||
|
||||
const optional<name::Component>&
|
||||
const std::optional<name::Component>&
|
||||
getFinalBlock() const
|
||||
{
|
||||
return m_metaInfo.getFinalBlock();
|
||||
}
|
||||
|
||||
Data&
|
||||
setFinalBlock(optional<name::Component> finalBlockId);
|
||||
setFinalBlock(std::optional<name::Component> finalBlockId);
|
||||
|
||||
public: // SignatureInfo fields
|
||||
/** @brief Get SignatureType
|
||||
* @return tlv::SignatureTypeValue, or -1 to indicate the signature is invalid
|
||||
/**
|
||||
* @brief Get the `SignatureType`.
|
||||
* @return tlv::SignatureTypeValue, or -1 to indicate the signature is invalid.
|
||||
*/
|
||||
int32_t
|
||||
getSignatureType() const noexcept
|
||||
@@ -310,17 +355,22 @@ public: // SignatureInfo fields
|
||||
return m_signatureInfo.getSignatureType();
|
||||
}
|
||||
|
||||
/** @brief Get KeyLocator
|
||||
/**
|
||||
* @brief Get the `KeyLocator` element.
|
||||
*/
|
||||
optional<KeyLocator>
|
||||
std::optional<KeyLocator>
|
||||
getKeyLocator() const noexcept
|
||||
{
|
||||
return m_signatureInfo.hasKeyLocator() ? make_optional(m_signatureInfo.getKeyLocator()) : nullopt;
|
||||
if (m_signatureInfo.hasKeyLocator()) {
|
||||
return m_signatureInfo.getKeyLocator();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
protected:
|
||||
/** @brief Clear wire encoding and cached FullName
|
||||
* @note This does not clear the SignatureValue.
|
||||
/**
|
||||
* @brief Clear wire encoding and cached FullName.
|
||||
* @note This does not clear the SignatureValue.
|
||||
*/
|
||||
void
|
||||
resetWire();
|
||||
@@ -331,9 +381,12 @@ private:
|
||||
Block m_content;
|
||||
SignatureInfo m_signatureInfo;
|
||||
Block m_signatureValue;
|
||||
// Add for QSCCP
|
||||
mutable std::optional<uint8_t> m_serviceClass;
|
||||
mutable std::optional<uint64_t> m_targetRate;
|
||||
|
||||
mutable Block m_wire;
|
||||
mutable Name m_fullName; ///< cached FullName computed from m_wire
|
||||
mutable Name m_fullName; // cached FullName computed from m_wire
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN
|
||||
@@ -359,3 +412,4 @@ operator!=(const Data& lhs, const Data& rhs)
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_CXX_DATA_HPP
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received copies of the GNU General Public License and GNU Lesser
|
||||
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#include "ndn-cxx/delegation-list.hpp"
|
||||
#include "ndn-cxx/util/ostream-joiner.hpp"
|
||||
|
||||
namespace ndn {
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<DelegationList>));
|
||||
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<DelegationList>));
|
||||
BOOST_CONCEPT_ASSERT((WireDecodable<DelegationList>));
|
||||
|
||||
DelegationList::DelegationList()
|
||||
: m_isSorted(true)
|
||||
{
|
||||
}
|
||||
|
||||
DelegationList::DelegationList(std::initializer_list<Delegation> dels)
|
||||
: m_isSorted(true)
|
||||
{
|
||||
for (const Delegation& del : dels) {
|
||||
this->insert(del, INS_REPLACE);
|
||||
}
|
||||
}
|
||||
|
||||
DelegationList::DelegationList(const Block& block, bool wantSort)
|
||||
{
|
||||
this->wireDecode(block, wantSort);
|
||||
}
|
||||
|
||||
bool
|
||||
DelegationList::isValidTlvType(uint32_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case tlv::Content:
|
||||
case tlv::ForwardingHint:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<encoding::Tag TAG>
|
||||
size_t
|
||||
DelegationList::wireEncode(EncodingImpl<TAG>& encoder, uint32_t type) const
|
||||
{
|
||||
if (!isValidTlvType(type)) {
|
||||
NDN_THROW(std::invalid_argument("Unexpected TLV-TYPE " + to_string(type) +
|
||||
" while encoding DelegationList"));
|
||||
}
|
||||
|
||||
if (this->size() == 0) {
|
||||
NDN_THROW(Error("Empty DelegationList"));
|
||||
}
|
||||
|
||||
// LinkContent ::= (type) TLV-LENGTH
|
||||
// Delegation+
|
||||
|
||||
// Delegation ::= LINK-DELEGATION-TYPE TLV-LENGTH
|
||||
// Preference
|
||||
// Name
|
||||
|
||||
// Preference ::= LINK-PREFERENCE-TYPE TLV-LENGTH
|
||||
// nonNegativeInteger
|
||||
|
||||
size_t totalLen = 0;
|
||||
for (auto i = m_dels.rbegin(); i != m_dels.rend(); ++i) {
|
||||
size_t delLen = 0;
|
||||
delLen += i->name.wireEncode(encoder);
|
||||
delLen += prependNonNegativeIntegerBlock(encoder, tlv::LinkPreference, i->preference);
|
||||
delLen += encoder.prependVarNumber(delLen);
|
||||
delLen += encoder.prependVarNumber(tlv::LinkDelegation);
|
||||
totalLen += delLen;
|
||||
}
|
||||
totalLen += encoder.prependVarNumber(totalLen);
|
||||
totalLen += encoder.prependVarNumber(type);
|
||||
return totalLen;
|
||||
}
|
||||
|
||||
template size_t
|
||||
DelegationList::wireEncode<encoding::EncoderTag>(EncodingBuffer&, uint32_t) const;
|
||||
|
||||
template size_t
|
||||
DelegationList::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, uint32_t) const;
|
||||
|
||||
void
|
||||
DelegationList::wireDecode(const Block& block, bool wantSort)
|
||||
{
|
||||
if (!isValidTlvType(block.type())) {
|
||||
NDN_THROW(Error("Unexpected TLV-TYPE " + to_string(block.type()) + " while decoding DelegationList"));
|
||||
}
|
||||
|
||||
m_isSorted = wantSort;
|
||||
m_dels.clear();
|
||||
|
||||
block.parse();
|
||||
for (const auto& del : block.elements()) {
|
||||
if (del.type() != tlv::LinkDelegation) {
|
||||
NDN_THROW(Error("Unexpected TLV-TYPE " + to_string(del.type()) + " while decoding Delegation"));
|
||||
}
|
||||
del.parse();
|
||||
|
||||
auto val = del.elements_begin();
|
||||
if (val == del.elements_end() || val->type() != tlv::LinkPreference) {
|
||||
NDN_THROW(Error("Missing Preference field in Delegation"));
|
||||
}
|
||||
uint64_t preference = 0;
|
||||
try {
|
||||
preference = readNonNegativeInteger(*val);
|
||||
}
|
||||
catch (const tlv::Error&) {
|
||||
NDN_THROW_NESTED(Error("Invalid Preference field in Delegation"));
|
||||
}
|
||||
|
||||
++val;
|
||||
if (val == del.elements_end() || val->type() != tlv::Name) {
|
||||
NDN_THROW(Error("Missing Name field in Delegation"));
|
||||
}
|
||||
Name name;
|
||||
try {
|
||||
name.wireDecode(*val);
|
||||
}
|
||||
catch (const tlv::Error&) {
|
||||
NDN_THROW_NESTED(Error("Invalid Name field in Delegation"));
|
||||
}
|
||||
|
||||
this->insertImpl(preference, name);
|
||||
}
|
||||
|
||||
if (this->size() == 0) {
|
||||
NDN_THROW(Error("Empty DelegationList"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DelegationList::sort()
|
||||
{
|
||||
if (m_isSorted) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<Delegation> dels;
|
||||
dels.swap(m_dels);
|
||||
|
||||
m_isSorted = true;
|
||||
for (const Delegation& del : dels) {
|
||||
this->insertImpl(del.preference, del.name);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DelegationList::insert(uint64_t preference, const Name& name,
|
||||
InsertConflictResolution onConflict)
|
||||
{
|
||||
switch (onConflict) {
|
||||
case INS_REPLACE:
|
||||
this->eraseImpl(nullopt, name);
|
||||
this->insertImpl(preference, name);
|
||||
return true;
|
||||
case INS_APPEND:
|
||||
this->insertImpl(preference, name);
|
||||
return true;
|
||||
case INS_SKIP:
|
||||
if (!std::any_of(m_dels.begin(), m_dels.end(),
|
||||
[name] (const Delegation& del) { return del.name == name; })) {
|
||||
this->insertImpl(preference, name);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NDN_THROW(std::invalid_argument("Unknown InsertConflictResolution"));
|
||||
}
|
||||
|
||||
void
|
||||
DelegationList::insertImpl(uint64_t preference, const Name& name)
|
||||
{
|
||||
if (!m_isSorted) {
|
||||
m_dels.push_back({preference, name});
|
||||
return;
|
||||
}
|
||||
|
||||
Delegation del{preference, name};
|
||||
auto pos = std::upper_bound(m_dels.begin(), m_dels.end(), del);
|
||||
m_dels.insert(pos, del);
|
||||
}
|
||||
|
||||
size_t
|
||||
DelegationList::eraseImpl(optional<uint64_t> preference, const Name& name)
|
||||
{
|
||||
size_t nErased = 0;
|
||||
for (auto i = m_dels.begin(); i != m_dels.end();) {
|
||||
if ((!preference || i->preference == *preference) &&
|
||||
i->name == name) {
|
||||
++nErased;
|
||||
i = m_dels.erase(i);
|
||||
}
|
||||
else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return nErased;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const DelegationList& dl)
|
||||
{
|
||||
os << '[';
|
||||
std::copy(dl.begin(), dl.end(), make_ostream_joiner(os, ','));
|
||||
return os << ']';
|
||||
}
|
||||
|
||||
} // namespace ndn
|
||||
@@ -1,264 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received copies of the GNU General Public License and GNU Lesser
|
||||
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_DELEGATION_LIST_HPP
|
||||
#define NDN_DELEGATION_LIST_HPP
|
||||
|
||||
#include "ndn-cxx/delegation.hpp"
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** \brief represents a list of Delegations
|
||||
* \sa https://named-data.net/doc/ndn-tlv/link.html
|
||||
*
|
||||
* Delegations are stored in an std::vector, under the assumption that there is usually only a
|
||||
* small number of Delegations, so that copying is acceptable when they are modified.
|
||||
*/
|
||||
class DelegationList
|
||||
{
|
||||
public:
|
||||
class Error : public tlv::Error
|
||||
{
|
||||
public:
|
||||
using tlv::Error::Error;
|
||||
};
|
||||
|
||||
/** \brief construct an empty DelegationList
|
||||
*/
|
||||
DelegationList();
|
||||
|
||||
/** \brief construct a sorted DelegationList with specified delegations
|
||||
*
|
||||
* This is equivalent to inserting each delegation into an empty DelegationList with INS_REPLACE
|
||||
* conflict resolution.
|
||||
*/
|
||||
DelegationList(std::initializer_list<Delegation> dels);
|
||||
|
||||
/** \brief decode a DelegationList
|
||||
* \sa wireDecode
|
||||
*/
|
||||
explicit
|
||||
DelegationList(const Block& block, bool wantSort = true);
|
||||
|
||||
/** \brief encode into wire format
|
||||
* \param encoder either an EncodingBuffer or an EncodingEstimator
|
||||
* \param type TLV-TYPE number, either Content (for \p Link) or ForwardingHint
|
||||
* \throw std::invalid_argument \p type is invalid
|
||||
* \throw Error there is no Delegation
|
||||
*/
|
||||
template<encoding::Tag TAG>
|
||||
size_t
|
||||
wireEncode(EncodingImpl<TAG>& encoder, uint32_t type = tlv::ForwardingHint) const;
|
||||
|
||||
/** \brief decode a DelegationList
|
||||
* \param block either a Content block (from \p Link) or a ForwardingHint block
|
||||
* \param wantSort if true, delegations are sorted
|
||||
* \throw Error the block cannot be parsed as a list of Delegations
|
||||
*/
|
||||
void
|
||||
wireDecode(const Block& block, bool wantSort = true);
|
||||
|
||||
bool
|
||||
isSorted() const noexcept
|
||||
{
|
||||
return m_isSorted;
|
||||
}
|
||||
|
||||
using const_iterator = std::vector<Delegation>::const_iterator;
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{
|
||||
return m_dels.begin();
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{
|
||||
return m_dels.end();
|
||||
}
|
||||
|
||||
NDN_CXX_NODISCARD bool
|
||||
empty() const noexcept
|
||||
{
|
||||
return m_dels.empty();
|
||||
}
|
||||
|
||||
size_t
|
||||
size() const noexcept
|
||||
{
|
||||
return m_dels.size();
|
||||
}
|
||||
|
||||
/** \brief get the i-th delegation
|
||||
* \pre i < size()
|
||||
*/
|
||||
const Delegation&
|
||||
operator[](size_t i) const
|
||||
{
|
||||
BOOST_ASSERT(i < size());
|
||||
return m_dels[i];
|
||||
}
|
||||
|
||||
/** \brief get the i-th delegation
|
||||
* \throw std::out_of_range i >= size()
|
||||
*/
|
||||
const Delegation&
|
||||
at(size_t i) const
|
||||
{
|
||||
return m_dels.at(i);
|
||||
}
|
||||
|
||||
public: // modifiers
|
||||
/** \brief sort the delegation list
|
||||
* \post isSorted() == true
|
||||
* \post Delegations are sorted in increasing preference order.
|
||||
*
|
||||
* A DelegationList can be constructed as sorted or unsorted. In most cases, it is recommended
|
||||
* to use a sorted DelegationList. An unsorted DelegationList is useful for extracting the i-th
|
||||
* delegation from a received ForwardingHint or Link object.
|
||||
*
|
||||
* This method turns an unsorted DelegationList into a sorted DelegationList.
|
||||
* If access to unsorted DelegationList is not needed, it is more efficient to sort the
|
||||
* DelegationList in wireDecode.
|
||||
*/
|
||||
void
|
||||
sort();
|
||||
|
||||
/** \brief what to do when inserting a duplicate name
|
||||
*/
|
||||
enum InsertConflictResolution {
|
||||
/** \brief existing delegation(s) with the same name are replaced with the new delegation
|
||||
*/
|
||||
INS_REPLACE,
|
||||
|
||||
/** \brief multiple delegations with the same name are kept in the DelegationList
|
||||
* \note This is NOT RECOMMENDED by Link specification.
|
||||
*/
|
||||
INS_APPEND,
|
||||
|
||||
/** \brief new delegation is not inserted if an existing delegation has the same name
|
||||
*/
|
||||
INS_SKIP
|
||||
};
|
||||
|
||||
/** \brief insert Delegation
|
||||
* \return whether inserted
|
||||
*/
|
||||
bool
|
||||
insert(uint64_t preference, const Name& name,
|
||||
InsertConflictResolution onConflict = INS_REPLACE);
|
||||
|
||||
/** \brief insert Delegation
|
||||
* \return whether inserted
|
||||
*/
|
||||
bool
|
||||
insert(const Delegation& del, InsertConflictResolution onConflict = INS_REPLACE)
|
||||
{
|
||||
return this->insert(del.preference, del.name, onConflict);
|
||||
}
|
||||
|
||||
/** \brief delete Delegation(s) with specified preference and name
|
||||
* \return count of erased Delegation(s)
|
||||
*/
|
||||
size_t
|
||||
erase(uint64_t preference, const Name& name)
|
||||
{
|
||||
return this->eraseImpl(preference, name);
|
||||
}
|
||||
|
||||
/** \brief delete Delegation(s) with matching preference and name
|
||||
* \return count of erased Delegation(s)
|
||||
*/
|
||||
size_t
|
||||
erase(const Delegation& del)
|
||||
{
|
||||
return this->eraseImpl(del.preference, del.name);
|
||||
}
|
||||
|
||||
/** \brief erase Delegation(s) with specified name
|
||||
* \return count of erased Delegation(s)
|
||||
*/
|
||||
size_t
|
||||
erase(const Name& name)
|
||||
{
|
||||
return this->eraseImpl(nullopt, name);
|
||||
}
|
||||
|
||||
private:
|
||||
static bool
|
||||
isValidTlvType(uint32_t type);
|
||||
|
||||
void
|
||||
insertImpl(uint64_t preference, const Name& name);
|
||||
|
||||
size_t
|
||||
eraseImpl(optional<uint64_t> preference, const Name& name);
|
||||
|
||||
private: // non-member operators
|
||||
// NOTE: the following "hidden friend" operators are available via
|
||||
// argument-dependent lookup only and must be defined inline.
|
||||
|
||||
/** \brief Compare whether two DelegationLists are equal.
|
||||
* \note Order matters! If two DelegationLists contain the same Delegations but at least one is
|
||||
* unsorted, they may compare unequal if the Delegations appear in different order.
|
||||
*/
|
||||
friend bool
|
||||
operator==(const DelegationList& lhs, const DelegationList& rhs)
|
||||
{
|
||||
return lhs.m_dels == rhs.m_dels;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(const DelegationList& lhs, const DelegationList& rhs)
|
||||
{
|
||||
return lhs.m_dels != rhs.m_dels;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isSorted;
|
||||
|
||||
/** \brief delegation container; its contents are sorted when \p m_isSorted is true
|
||||
* \note This container is a member field rather than a base class, in order to ensure contents
|
||||
* are sorted when \p m_isSorted is true.
|
||||
* \note A vector is chosen instead of a std::set, so that the container can be unsorted when
|
||||
* \p m_isSorted is false. This container is expected to have less than seven items, and
|
||||
* therefore the overhead of moving items during insertion and deletion is small.
|
||||
*/
|
||||
std::vector<Delegation> m_dels;
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN
|
||||
extern template size_t
|
||||
DelegationList::wireEncode<encoding::EncoderTag>(EncodingBuffer&, uint32_t) const;
|
||||
|
||||
extern template size_t
|
||||
DelegationList::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, uint32_t) const;
|
||||
#endif
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const DelegationList& dl);
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_DELEGATION_LIST_HPP
|
||||
@@ -1,89 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received copies of the GNU General Public License and GNU Lesser
|
||||
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_DELEGATION_HPP
|
||||
#define NDN_DELEGATION_HPP
|
||||
|
||||
#include "ndn-cxx/name.hpp"
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** \brief Represents a %Delegation.
|
||||
* \sa https://named-data.net/doc/NDN-packet-spec/0.3/link.html
|
||||
*/
|
||||
class Delegation
|
||||
{
|
||||
private: // non-member operators
|
||||
// NOTE: the following "hidden friend" operators are available via
|
||||
// argument-dependent lookup only and must be defined inline.
|
||||
|
||||
friend bool
|
||||
operator==(const Delegation& lhs, const Delegation& rhs)
|
||||
{
|
||||
return !(lhs != rhs);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(const Delegation& lhs, const Delegation& rhs)
|
||||
{
|
||||
return lhs.preference != rhs.preference ||
|
||||
lhs.name != rhs.name;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator<(const Delegation& lhs, const Delegation& rhs)
|
||||
{
|
||||
return std::tie(lhs.preference, lhs.name) <
|
||||
std::tie(rhs.preference, rhs.name);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator<=(const Delegation& lhs, const Delegation& rhs)
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator>(const Delegation& lhs, const Delegation& rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator>=(const Delegation& lhs, const Delegation& rhs)
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const Delegation& d)
|
||||
{
|
||||
return os << d.name << '(' << d.preference << ')';
|
||||
}
|
||||
|
||||
public:
|
||||
uint64_t preference;
|
||||
Name name;
|
||||
};
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_DELEGATION_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,22 +19,11 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_DETAIL_ASIO_FWD_HPP
|
||||
#define NDN_DETAIL_ASIO_FWD_HPP
|
||||
#ifndef NDN_CXX_DETAIL_ASIO_FWD_HPP
|
||||
#define NDN_CXX_DETAIL_ASIO_FWD_HPP
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
#if BOOST_VERSION >= 106600
|
||||
namespace boost::asio {
|
||||
class io_context;
|
||||
using io_service = io_context;
|
||||
#else
|
||||
class io_service;
|
||||
#endif // BOOST_VERSION >= 106600
|
||||
} // namespace boost::asio
|
||||
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
|
||||
#endif // NDN_DETAIL_ASIO_FWD_HPP
|
||||
#endif // NDN_CXX_DETAIL_ASIO_FWD_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -21,8 +21,7 @@
|
||||
|
||||
#include "ndn-cxx/detail/cancel-handle.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace detail {
|
||||
namespace ndn::detail {
|
||||
|
||||
void
|
||||
CancelHandle::cancel() const
|
||||
@@ -33,5 +32,4 @@ CancelHandle::cancel() const
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ndn
|
||||
} // namespace ndn::detail
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,15 +19,18 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_DETAIL_CANCEL_HANDLE_HPP
|
||||
#define NDN_DETAIL_CANCEL_HANDLE_HPP
|
||||
#ifndef NDN_CXX_DETAIL_CANCEL_HANDLE_HPP
|
||||
#define NDN_CXX_DETAIL_CANCEL_HANDLE_HPP
|
||||
|
||||
#include "ndn-cxx/detail/common.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace detail {
|
||||
/**
|
||||
* \brief Contains implementation details that are not part of the ndn-cxx public API.
|
||||
*/
|
||||
namespace ndn::detail {
|
||||
|
||||
/** \brief Handle to cancel an operation.
|
||||
/**
|
||||
* \brief Handle to cancel an operation.
|
||||
*/
|
||||
class CancelHandle
|
||||
{
|
||||
@@ -52,12 +55,13 @@ private:
|
||||
inline
|
||||
CancelHandle::CancelHandle() noexcept = default;
|
||||
|
||||
/** \brief Cancels an operation automatically upon destruction.
|
||||
/**
|
||||
* \brief Cancels an operation automatically upon destruction.
|
||||
*/
|
||||
template<typename HandleT>
|
||||
class ScopedCancelHandle
|
||||
{
|
||||
static_assert(std::is_convertible<HandleT*, CancelHandle*>::value,
|
||||
static_assert(std::is_convertible_v<HandleT*, CancelHandle*>,
|
||||
"HandleT must publicly derive from CancelHandle");
|
||||
|
||||
public:
|
||||
@@ -133,7 +137,6 @@ private:
|
||||
template<typename T>
|
||||
ScopedCancelHandle<T>::ScopedCancelHandle() noexcept = default;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ndn
|
||||
} // namespace ndn::detail
|
||||
|
||||
#endif // NDN_DETAIL_CANCEL_HANDLE_HPP
|
||||
#endif // NDN_CXX_DETAIL_CANCEL_HANDLE_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,8 +19,8 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_DETAIL_CF_RELEASER_OSX_HPP
|
||||
#define NDN_DETAIL_CF_RELEASER_OSX_HPP
|
||||
#ifndef NDN_CXX_DETAIL_CF_RELEASER_OSX_HPP
|
||||
#define NDN_CXX_DETAIL_CF_RELEASER_OSX_HPP
|
||||
|
||||
#include "ndn-cxx/detail/common.hpp"
|
||||
|
||||
@@ -30,8 +30,7 @@
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
namespace ndn {
|
||||
namespace detail {
|
||||
namespace ndn::detail {
|
||||
|
||||
/**
|
||||
* @brief Helper class to wrap CoreFoundation object pointers
|
||||
@@ -145,7 +144,6 @@ private:
|
||||
T m_typeRef;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ndn
|
||||
} // namespace ndn::detail
|
||||
|
||||
#endif // NDN_DETAIL_CF_RELEASER_OSX_HPP
|
||||
#endif // NDN_CXX_DETAIL_CF_RELEASER_OSX_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -21,9 +21,7 @@
|
||||
|
||||
#include "ndn-cxx/detail/cf-string-osx.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace detail {
|
||||
namespace cfstring {
|
||||
namespace ndn::detail::cfstring {
|
||||
|
||||
CFReleaser<CFStringRef>
|
||||
fromBuffer(const uint8_t* buf, size_t buflen)
|
||||
@@ -66,6 +64,4 @@ toStdString(CFStringRef cfStr)
|
||||
return str;
|
||||
}
|
||||
|
||||
} // namespace cfstring
|
||||
} // namespace detail
|
||||
} // namespace ndn
|
||||
} // namespace ndn::detail::cfstring
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,8 +19,8 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_DETAIL_CF_STRING_OSX_HPP
|
||||
#define NDN_DETAIL_CF_STRING_OSX_HPP
|
||||
#ifndef NDN_CXX_DETAIL_CF_STRING_OSX_HPP
|
||||
#define NDN_CXX_DETAIL_CF_STRING_OSX_HPP
|
||||
|
||||
#include "ndn-cxx/detail/common.hpp"
|
||||
|
||||
@@ -36,9 +36,7 @@
|
||||
* This file contains utilities to deal with Apple Core Foundation's CFString and related types.
|
||||
*/
|
||||
|
||||
namespace ndn {
|
||||
namespace detail {
|
||||
namespace cfstring {
|
||||
namespace ndn::detail::cfstring {
|
||||
|
||||
/**
|
||||
* @brief Create a CFString by copying bytes from a raw buffer
|
||||
@@ -61,8 +59,6 @@ fromStdString(const std::string& str);
|
||||
std::string
|
||||
toStdString(CFStringRef cfStr);
|
||||
|
||||
} // namespace cfstring
|
||||
} // namespace detail
|
||||
} // namespace ndn
|
||||
} // namespace ndn::detail::cfstring
|
||||
|
||||
#endif // NDN_DETAIL_CF_STRING_OSX_HPP
|
||||
#endif // NDN_CXX_DETAIL_CF_STRING_OSX_HPP
|
||||
+14
-19
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -25,14 +25,14 @@
|
||||
* Aliases imported in this file MUST NOT be used outside of ndn-cxx.
|
||||
*/
|
||||
|
||||
#ifndef NDN_DETAIL_COMMON_HPP
|
||||
#define NDN_DETAIL_COMMON_HPP
|
||||
#ifndef NDN_CXX_DETAIL_COMMON_HPP
|
||||
#define NDN_CXX_DETAIL_COMMON_HPP
|
||||
|
||||
#include "ndn-cxx/detail/config.hpp"
|
||||
|
||||
// require C++14
|
||||
#if __cplusplus < 201402L
|
||||
#error "ndn-cxx applications must be compiled using the C++14 standard (-std=c++14)"
|
||||
// require C++17
|
||||
#if __cplusplus < 201703L
|
||||
#error "ndn-cxx applications must be compiled using the C++17 standard (-std=c++17)"
|
||||
#endif
|
||||
|
||||
// ndn-cxx specific macros declared in this and other headers must have NDN_CXX_ prefix
|
||||
@@ -49,15 +49,14 @@
|
||||
#define NDN_CXX_PROTECTED_WITH_TESTS_ELSE_PRIVATE private
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
@@ -69,23 +68,19 @@ using std::weak_ptr;
|
||||
using std::make_shared;
|
||||
using std::make_unique;
|
||||
|
||||
using std::static_pointer_cast;
|
||||
using std::dynamic_pointer_cast;
|
||||
using std::const_pointer_cast;
|
||||
|
||||
using std::function;
|
||||
using std::bind;
|
||||
using std::ref;
|
||||
using std::cref;
|
||||
|
||||
using std::to_string;
|
||||
using namespace std::string_literals;
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
/// \cond
|
||||
// Bug 2109 workaround
|
||||
#if BOOST_VERSION < 107600
|
||||
#define BOOST_BIND_NO_PLACEHOLDERS
|
||||
#include <boost/is_placeholder.hpp>
|
||||
namespace boost {
|
||||
@@ -108,10 +103,10 @@ NDN_CXX_SPECIALIZE_BOOST_IS_PLACEHOLDER_FOR_STD_PLACEHOLDER(8)
|
||||
NDN_CXX_SPECIALIZE_BOOST_IS_PLACEHOLDER_FOR_STD_PLACEHOLDER(9)
|
||||
#undef NDN_CXX_SPECIALIZE_BOOST_IS_PLACEHOLDER_FOR_STD_PLACEHOLDER
|
||||
} // namespace boost
|
||||
#endif // BOOST_VERSION < 107600
|
||||
/// \endcond
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
|
||||
namespace ndn {
|
||||
@@ -121,4 +116,4 @@ using boost::noncopyable;
|
||||
#include "ndn-cxx/util/backports.hpp"
|
||||
#include "ndn-cxx/util/exception.hpp"
|
||||
|
||||
#endif // NDN_DETAIL_COMMON_HPP
|
||||
#endif // NDN_CXX_DETAIL_COMMON_HPP
|
||||
@@ -13,7 +13,7 @@
|
||||
#define NONSTD_SCOPE_LITE_HPP
|
||||
|
||||
#define scope_lite_MAJOR 0
|
||||
#define scope_lite_MINOR 1
|
||||
#define scope_lite_MINOR 2
|
||||
#define scope_lite_PATCH 0
|
||||
|
||||
#define scope_lite_VERSION scope_STRINGIFY(scope_lite_MAJOR) "." scope_STRINGIFY(scope_lite_MINOR) "." scope_STRINGIFY(scope_lite_PATCH)
|
||||
@@ -27,15 +27,33 @@
|
||||
#define scope_SCOPE_NONSTD 1
|
||||
#define scope_SCOPE_STD 2
|
||||
|
||||
// tweak header support:
|
||||
|
||||
#ifdef __has_include
|
||||
# if __has_include(<nonstd/scope.tweak.hpp>)
|
||||
# include <nonstd/scope.tweak.hpp>
|
||||
# endif
|
||||
#define scope_HAVE_TWEAK_HEADER 1
|
||||
#else
|
||||
#define scope_HAVE_TWEAK_HEADER 0
|
||||
//# pragma message("scope.hpp: Note: Tweak header not supported.")
|
||||
#endif
|
||||
|
||||
// scope selection and configuration:
|
||||
|
||||
#if !defined( scope_CONFIG_SELECT_SCOPE )
|
||||
# define scope_CONFIG_SELECT_SCOPE ( scope_HAVE_STD_SCOPE ? scope_SCOPE_STD : scope_SCOPE_NONSTD )
|
||||
#endif
|
||||
|
||||
// #if !defined( scope_CONFIG_STRICT )
|
||||
// # define scope_CONFIG_STRICT 0
|
||||
// #endif
|
||||
#if !defined( scope_CONFIG_NO_EXTENSIONS )
|
||||
# define scope_CONFIG_NO_EXTENSIONS 0
|
||||
#endif
|
||||
|
||||
// C++ language version detection (C++20 is speculative):
|
||||
#if !defined( scope_CONFIG_NO_CONSTEXPR )
|
||||
# define scope_CONFIG_NO_CONSTEXPR (scope_CONFIG_NO_EXTENSIONS || !scope_CPP20_OR_GREATER)
|
||||
#endif
|
||||
|
||||
// C++ language version detection (C++23 is speculative):
|
||||
// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
|
||||
|
||||
#ifndef scope_CPLUSPLUS
|
||||
@@ -50,12 +68,16 @@
|
||||
#define scope_CPP11_OR_GREATER ( scope_CPLUSPLUS >= 201103L )
|
||||
#define scope_CPP14_OR_GREATER ( scope_CPLUSPLUS >= 201402L )
|
||||
#define scope_CPP17_OR_GREATER ( scope_CPLUSPLUS >= 201703L )
|
||||
#define scope_CPP20_OR_GREATER ( scope_CPLUSPLUS >= 202000L )
|
||||
#define scope_CPP20_OR_GREATER ( scope_CPLUSPLUS >= 202002L )
|
||||
#define scope_CPP23_OR_GREATER ( scope_CPLUSPLUS >= 202300L )
|
||||
|
||||
// Use C++yy <scope> if available and requested:
|
||||
// Note: __cpp_lib_experimental_scope: a value of at least 201902 indicates that the scope guard are supported
|
||||
|
||||
#if scope_CPP20_OR_GREATER && defined(__has_include )
|
||||
# if __has_include( <scope> )
|
||||
# if __has_include( <scope> )
|
||||
# define scope_HAVE_STD_SCOPE 1
|
||||
# elif __has_include( <experimental/scope> )
|
||||
# define scope_HAVE_STD_SCOPE 1
|
||||
# else
|
||||
# define scope_HAVE_STD_SCOPE 0
|
||||
@@ -69,6 +91,10 @@
|
||||
//
|
||||
// Using std <scope>:
|
||||
//
|
||||
// ToDo:
|
||||
// - choose <scope> or <experimental/scope>.
|
||||
// - use correct namespace in using below.
|
||||
//
|
||||
|
||||
#if scope_USES_STD_SCOPE
|
||||
|
||||
@@ -203,11 +229,14 @@ namespace nonstd
|
||||
#define scope_HAVE_IS_COPY_CONSTRUCTIBLE scope_CPP11_110
|
||||
#define scope_HAVE_IS_MOVE_CONSTRUCTIBLE scope_CPP11_110
|
||||
#define scope_HAVE_IS_NOTHROW_CONSTRUCTIBLE scope_CPP11_110
|
||||
#define scope_HAVE_IS_NOTHROW_COPY_CONSTRUCTIBLE scope_CPP11_110
|
||||
#define scope_HAVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE scope_CPP11_110
|
||||
#define scope_HAVE_IS_COPY_ASSIGNABLE scope_CPP11_110
|
||||
#define scope_HAVE_IS_NOTHROW_ASSIGNABLE scope_CPP11_110
|
||||
#define scope_HAVE_IS_NOTHROW_MOVE_ASSIGNABLE scope_CPP11_110
|
||||
|
||||
#define scope_HAVE_REFERENCE_WRAPPER scope_CPP11_110
|
||||
|
||||
#define scope_HAVE_REMOVE_CV scope_CPP11_90
|
||||
#define scope_HAVE_REMOVE_REFERENCE scope_CPP11_90
|
||||
|
||||
@@ -242,6 +271,12 @@ namespace nonstd
|
||||
# define scope_constexpr14 /*constexpr*/
|
||||
#endif
|
||||
|
||||
#if !scope_CONFIG_NO_CONSTEXPR
|
||||
#define scope_constexpr_ext constexpr
|
||||
#else
|
||||
# define scope_constexpr_ext /*constexpr*/
|
||||
#endif
|
||||
|
||||
#if scope_HAVE( IS_DELETE )
|
||||
# define scope_is_delete = delete
|
||||
# define scope_is_delete_access public
|
||||
@@ -331,7 +366,7 @@ namespace nonstd
|
||||
namespace nonstd {
|
||||
namespace scope {
|
||||
|
||||
// for bit_ENABLE_IF_():
|
||||
// for scope_ENABLE_IF_():
|
||||
|
||||
/*enum*/ class enabler{};
|
||||
|
||||
@@ -457,7 +492,6 @@ struct conditional<false, T, F> { typedef F type; };
|
||||
template< class T > struct remove_reference{ typedef T type; };
|
||||
#endif
|
||||
|
||||
|
||||
#if scope_HAVE( REFERENCE_WRAPPER )
|
||||
using std::reference_wrapper;
|
||||
#else
|
||||
@@ -542,6 +576,28 @@ struct type_identity { typedef T type; };
|
||||
|
||||
} // namepsace std20
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if scope_CONFIG_NO_CONSTEXPR
|
||||
|
||||
using std17::uncaught_exceptions;
|
||||
|
||||
#else
|
||||
constexpr int uncaught_exceptions() noexcept
|
||||
{
|
||||
if ( std::is_constant_evaluated() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return std17::uncaught_exceptions();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// For reference:
|
||||
//
|
||||
@@ -630,7 +686,7 @@ public:
|
||||
&& std11::is_constructible<EF, Fn>::value
|
||||
))
|
||||
>
|
||||
explicit scope_exit( Fn&& fn )
|
||||
scope_constexpr_ext explicit scope_exit( Fn&& fn )
|
||||
scope_noexcept_op
|
||||
((
|
||||
std11::is_nothrow_constructible<EF, Fn>::value
|
||||
@@ -643,7 +699,7 @@ public:
|
||||
, execute_on_destruction( true )
|
||||
{}
|
||||
|
||||
scope_exit( scope_exit && other )
|
||||
scope_constexpr_ext scope_exit( scope_exit && other )
|
||||
scope_noexcept_op
|
||||
((
|
||||
std11::is_nothrow_move_constructible<EF>::value
|
||||
@@ -655,22 +711,22 @@ public:
|
||||
other.release();
|
||||
}
|
||||
|
||||
~scope_exit() scope_noexcept
|
||||
scope_constexpr_ext ~scope_exit() scope_noexcept
|
||||
{
|
||||
if ( execute_on_destruction )
|
||||
exit_function();
|
||||
}
|
||||
|
||||
void release() scope_noexcept
|
||||
scope_constexpr_ext void release() scope_noexcept
|
||||
{
|
||||
execute_on_destruction = false;
|
||||
}
|
||||
|
||||
scope_is_delete_access:
|
||||
scope_exit( scope_exit const & ) scope_is_delete;
|
||||
scope_constexpr_ext scope_exit( scope_exit const & ) scope_is_delete;
|
||||
|
||||
scope_exit & operator=( scope_exit const & ) scope_is_delete;
|
||||
scope_exit & operator=( scope_exit && ) scope_is_delete;
|
||||
scope_constexpr_ext scope_exit & operator=( scope_exit const & ) scope_is_delete;
|
||||
scope_constexpr_ext scope_exit & operator=( scope_exit && ) scope_is_delete;
|
||||
|
||||
private:
|
||||
EF exit_function;
|
||||
@@ -689,7 +745,7 @@ public:
|
||||
&& std11::is_constructible<EF, Fn>::value
|
||||
))
|
||||
>
|
||||
explicit scope_fail( Fn&& fn )
|
||||
scope_constexpr_ext explicit scope_fail( Fn&& fn )
|
||||
scope_noexcept_op
|
||||
((
|
||||
std11::is_nothrow_constructible<EF, Fn>::value
|
||||
@@ -698,10 +754,10 @@ public:
|
||||
: exit_function(
|
||||
conditional_forward<Fn>( std::forward<Fn>(fn)
|
||||
, std11::bool_constant< std11::is_nothrow_constructible<EF, Fn>::value >() ) )
|
||||
, uncaught_on_creation( std17::uncaught_exceptions() )
|
||||
, uncaught_on_creation( detail::uncaught_exceptions() )
|
||||
{}
|
||||
|
||||
scope_fail( scope_fail && other )
|
||||
scope_constexpr_ext scope_fail( scope_fail && other )
|
||||
scope_noexcept_op
|
||||
((
|
||||
std11::is_nothrow_move_constructible<EF>::value
|
||||
@@ -713,26 +769,26 @@ public:
|
||||
other.release();
|
||||
}
|
||||
|
||||
~scope_fail() scope_noexcept
|
||||
scope_constexpr_ext ~scope_fail() scope_noexcept
|
||||
{
|
||||
if ( uncaught_on_creation < std17::uncaught_exceptions() )
|
||||
if ( uncaught_on_creation < detail::uncaught_exceptions() )
|
||||
exit_function();
|
||||
}
|
||||
|
||||
void release() scope_noexcept
|
||||
scope_constexpr_ext void release() scope_noexcept
|
||||
{
|
||||
uncaught_on_creation = std::numeric_limits<int>::max();
|
||||
}
|
||||
|
||||
scope_is_delete_access:
|
||||
scope_fail( scope_fail const & ) scope_is_delete;
|
||||
scope_constexpr_ext scope_fail( scope_fail const & ) scope_is_delete;
|
||||
|
||||
scope_fail & operator=( scope_fail const & ) scope_is_delete;
|
||||
scope_fail & operator=( scope_fail && ) scope_is_delete;
|
||||
scope_constexpr_ext scope_fail & operator=( scope_fail const & ) scope_is_delete;
|
||||
scope_constexpr_ext scope_fail & operator=( scope_fail && ) scope_is_delete;
|
||||
|
||||
private:
|
||||
EF exit_function;
|
||||
int uncaught_on_creation; // { std17::uncaught_exceptions() };
|
||||
int uncaught_on_creation; // { detail::uncaught_exceptions() };
|
||||
};
|
||||
|
||||
// scope_success:
|
||||
@@ -747,7 +803,7 @@ public:
|
||||
&& std11::is_constructible<EF, Fn>::value
|
||||
))
|
||||
>
|
||||
explicit scope_success( Fn&& fn )
|
||||
scope_constexpr_ext explicit scope_success( Fn&& fn )
|
||||
scope_noexcept_op
|
||||
((
|
||||
std11::is_nothrow_constructible<EF, Fn>::value
|
||||
@@ -756,10 +812,10 @@ public:
|
||||
: exit_function(
|
||||
conditional_forward<Fn>( std::forward<Fn>(fn)
|
||||
, std11::bool_constant< std11::is_nothrow_constructible<EF, Fn>::value >() ) )
|
||||
, uncaught_on_creation( std17::uncaught_exceptions() )
|
||||
, uncaught_on_creation( detail::uncaught_exceptions() )
|
||||
{}
|
||||
|
||||
scope_success( scope_success && other )
|
||||
scope_constexpr_ext scope_success( scope_success && other )
|
||||
scope_noexcept_op
|
||||
((
|
||||
std11::is_nothrow_move_constructible<EF>::value
|
||||
@@ -771,26 +827,26 @@ public:
|
||||
other.release();
|
||||
}
|
||||
|
||||
~scope_success() scope_noexcept
|
||||
scope_constexpr_ext ~scope_success() scope_noexcept
|
||||
{
|
||||
if ( uncaught_on_creation >= std17::uncaught_exceptions() )
|
||||
if ( uncaught_on_creation >= detail::uncaught_exceptions() )
|
||||
exit_function();
|
||||
}
|
||||
|
||||
void release() scope_noexcept
|
||||
scope_constexpr_ext void release() scope_noexcept
|
||||
{
|
||||
uncaught_on_creation = -1;
|
||||
}
|
||||
|
||||
scope_is_delete_access:
|
||||
scope_success( scope_success const & ) scope_is_delete;
|
||||
scope_constexpr_ext scope_success( scope_success const & ) scope_is_delete;
|
||||
|
||||
scope_success & operator=( scope_success const & ) scope_is_delete;
|
||||
scope_success & operator=( scope_success && ) scope_is_delete;
|
||||
scope_constexpr_ext scope_success & operator=( scope_success const & ) scope_is_delete;
|
||||
scope_constexpr_ext scope_success & operator=( scope_success && ) scope_is_delete;
|
||||
|
||||
private:
|
||||
EF exit_function;
|
||||
int uncaught_on_creation; // { std17::uncaught_exceptions() };
|
||||
int uncaught_on_creation; // { detail::uncaught_exceptions() };
|
||||
};
|
||||
|
||||
#if scope_HAVE( DEDUCTION_GUIDES )
|
||||
@@ -802,6 +858,7 @@ template< class EF > scope_success(EF) -> scope_success<EF>;
|
||||
// optional factory functions (should at least be present for LFTS3):
|
||||
|
||||
template< class EF >
|
||||
scope_constexpr_ext
|
||||
scope_exit<typename std11::decay<EF>::type>
|
||||
make_scope_exit( EF && exit_function )
|
||||
{
|
||||
@@ -809,6 +866,7 @@ make_scope_exit( EF && exit_function )
|
||||
}
|
||||
|
||||
template< class EF >
|
||||
scope_constexpr_ext
|
||||
scope_fail<typename std11::decay<EF>::type>
|
||||
make_scope_fail( EF && exit_function )
|
||||
{
|
||||
@@ -816,6 +874,7 @@ make_scope_fail( EF && exit_function )
|
||||
}
|
||||
|
||||
template< class EF >
|
||||
scope_constexpr_ext
|
||||
scope_success<typename std11::decay<EF>::type>
|
||||
make_scope_success( EF && exit_function )
|
||||
{
|
||||
@@ -894,18 +953,19 @@ public:
|
||||
, execute_on_reset( execute )
|
||||
{}
|
||||
|
||||
// TODO:Move constructor.
|
||||
// Move constructor.
|
||||
//
|
||||
// The stored resource handle is initialized from the one of other, using std::move if
|
||||
// std::is_nothrow_move_constructible_v<RS> is true.
|
||||
|
||||
//
|
||||
// If initialization of the stored resource handle throws an exception, other is not modified.
|
||||
|
||||
//
|
||||
// Then, the deleter is initialized with the one of other, using std::move if
|
||||
// std::is_nothrow_move_constructible_v<D> is true.
|
||||
|
||||
//
|
||||
// If initialization of the deleter throws an exception and std::is_nothrow_move_constructible_v<RS> is true and
|
||||
// other owns the resource, calls the deleter of other with res_ to dispose the resource, then calls other.release().
|
||||
|
||||
//
|
||||
// After construction, the constructed unique_resource owns its resource if and only if other owned the resource before
|
||||
// the construction, and other is set to not own the resource.
|
||||
|
||||
@@ -920,7 +980,7 @@ public:
|
||||
{}
|
||||
catch(...)
|
||||
{
|
||||
if ( other.execute_on_reset && std::is_nothrow_move_constructible<R>::value )
|
||||
if ( other.execute_on_reset && std11::is_nothrow_move_constructible<R>::value )
|
||||
{
|
||||
other.get_deleter()( this->get() );
|
||||
other.release();
|
||||
@@ -1179,7 +1239,7 @@ struct on_fail_policy
|
||||
mutable int ucount_;
|
||||
|
||||
on_fail_policy()
|
||||
: ucount_( std17::uncaught_exceptions() )
|
||||
: ucount_( detail::uncaught_exceptions() )
|
||||
{}
|
||||
|
||||
on_fail_policy( on_fail_policy const & other )
|
||||
@@ -1195,7 +1255,7 @@ struct on_fail_policy
|
||||
|
||||
bool perform()
|
||||
{
|
||||
return ucount_ < std17::uncaught_exceptions();
|
||||
return ucount_ < detail::uncaught_exceptions();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1204,7 +1264,7 @@ struct on_success_policy
|
||||
mutable int ucount_;
|
||||
|
||||
on_success_policy()
|
||||
: ucount_( std17::uncaught_exceptions() )
|
||||
: ucount_( detail::uncaught_exceptions() )
|
||||
{}
|
||||
|
||||
on_success_policy( on_success_policy const & other )
|
||||
@@ -1220,18 +1280,15 @@ struct on_success_policy
|
||||
|
||||
bool perform()
|
||||
{
|
||||
return ucount_ >= std17::uncaught_exceptions();
|
||||
return ucount_ >= detail::uncaught_exceptions();
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Policy >
|
||||
template< typename Policy, typename Action >
|
||||
class scope_guard : public Policy
|
||||
{
|
||||
public:
|
||||
typedef void (*Action)();
|
||||
|
||||
template< typename Fn >
|
||||
scope_guard( Fn action )
|
||||
scope_guard( Action action )
|
||||
: Policy()
|
||||
, action_( action )
|
||||
{}
|
||||
@@ -1254,25 +1311,25 @@ private:
|
||||
Action action_;
|
||||
};
|
||||
|
||||
class scope_exit : public scope_guard< on_exit_policy >
|
||||
template< typename Fn = void(*)() >
|
||||
class scope_exit : public scope_guard< on_exit_policy, Fn >
|
||||
{
|
||||
public:
|
||||
template< typename Fn >
|
||||
scope_exit( Fn action ) : scope_guard( action ) {}
|
||||
scope_exit( Fn action ) : scope_guard<on_exit_policy, Fn>( action ) {}
|
||||
};
|
||||
|
||||
class scope_fail : public scope_guard< on_fail_policy >
|
||||
template< typename Fn = void(*)() >
|
||||
class scope_fail : public scope_guard< on_fail_policy, Fn >
|
||||
{
|
||||
public:
|
||||
template< typename Fn >
|
||||
scope_fail( Fn action ) : scope_guard( action ) {}
|
||||
scope_fail( Fn action ) : scope_guard<on_fail_policy, Fn>( action ) {}
|
||||
};
|
||||
|
||||
class scope_success : public scope_guard< on_success_policy >
|
||||
template< typename Fn = void(*)() >
|
||||
class scope_success : public scope_guard< on_success_policy, Fn >
|
||||
{
|
||||
public:
|
||||
template< typename Fn >
|
||||
scope_success( Fn action ) : scope_guard( action ) {}
|
||||
scope_success( Fn action ) : scope_guard<on_success_policy, Fn>( action ) {}
|
||||
};
|
||||
|
||||
// unique_resource (C++98):
|
||||
@@ -1379,21 +1436,21 @@ private:
|
||||
};
|
||||
|
||||
template< class EF >
|
||||
scope_exit make_scope_exit( EF action )
|
||||
scope_exit<EF> make_scope_exit( EF action )
|
||||
{
|
||||
return scope_exit( action );
|
||||
return scope_exit<EF>( action );
|
||||
}
|
||||
|
||||
template< class EF >
|
||||
scope_fail make_scope_fail( EF action )
|
||||
scope_fail<EF> make_scope_fail( EF action )
|
||||
{
|
||||
return scope_fail( action );
|
||||
return scope_fail<EF>( action );
|
||||
}
|
||||
|
||||
template< class EF >
|
||||
scope_success make_scope_success( EF action )
|
||||
scope_success<EF> make_scope_success( EF action )
|
||||
{
|
||||
return scope_success( action );
|
||||
return scope_success<EF>( action );
|
||||
}
|
||||
|
||||
template< class R, class D, class S >
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2022 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,24 +19,24 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_DETAIL_PACKET_BASE_HPP
|
||||
#define NDN_DETAIL_PACKET_BASE_HPP
|
||||
#ifndef NDN_CXX_DETAIL_PACKET_BASE_HPP
|
||||
#define NDN_CXX_DETAIL_PACKET_BASE_HPP
|
||||
|
||||
#include "ndn-cxx/detail/tag-host.hpp"
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** \brief base class to allow simple management of packet tags
|
||||
/** \brief Base class to allow simple management of packet tags.
|
||||
*/
|
||||
class PacketBase : public TagHost
|
||||
{
|
||||
public:
|
||||
/** \brief get the value of the CongestionMark tag
|
||||
/** \brief Get the value of the CongestionMark tag.
|
||||
*/
|
||||
uint64_t
|
||||
getCongestionMark() const;
|
||||
|
||||
/** \brief set the CongestionMark tag to the specified value
|
||||
/** \brief Set the CongestionMark tag to the specified value.
|
||||
*/
|
||||
void
|
||||
setCongestionMark(uint64_t mark);
|
||||
@@ -44,4 +44,4 @@ public:
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_DETAIL_PACKET_BASE_HPP
|
||||
#endif // NDN_CXX_DETAIL_PACKET_BASE_HPP
|
||||
+23
-19
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,8 +19,8 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_DETAIL_TAG_HOST_HPP
|
||||
#define NDN_DETAIL_TAG_HOST_HPP
|
||||
#ifndef NDN_CXX_DETAIL_TAG_HOST_HPP
|
||||
#define NDN_CXX_DETAIL_TAG_HOST_HPP
|
||||
|
||||
#include "ndn-cxx/detail/common.hpp"
|
||||
#include "ndn-cxx/tag.hpp"
|
||||
@@ -29,29 +29,34 @@
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** \brief Base class to store tag information (e.g., inside Interest and Data packets)
|
||||
/**
|
||||
* \brief Base class to store tag information, e.g., inside Interest and Data packets.
|
||||
*/
|
||||
class TagHost
|
||||
{
|
||||
public:
|
||||
/** \brief get a tag item
|
||||
* \tparam T type of the tag, which must be a subclass of ndn::Tag
|
||||
* \retval nullptr if no Tag of type T is stored
|
||||
/**
|
||||
* \brief Get a tag item.
|
||||
* \tparam T type of the tag, which must be a subclass of ndn::Tag
|
||||
* \retval nullptr if no Tag of type T is stored
|
||||
*/
|
||||
template<typename T>
|
||||
shared_ptr<T>
|
||||
getTag() const;
|
||||
|
||||
/** \brief set a tag item
|
||||
* \tparam T type of the tag, which must be a subclass of ndn::Tag
|
||||
* \note Tag can be set even on a const tag host instance
|
||||
/**
|
||||
* \brief Set (add or replace) a tag item.
|
||||
* \tparam T type of the tag, which must be a subclass of ndn::Tag
|
||||
* \note Tag can be set even on a const tag host instance
|
||||
*/
|
||||
template<typename T>
|
||||
void
|
||||
setTag(shared_ptr<T> tag) const;
|
||||
|
||||
/** \brief remove tag item
|
||||
* \note Tag can be removed even on a const tag host instance
|
||||
/**
|
||||
* \brief Remove a tag item.
|
||||
* \tparam T type of the tag, which must be a subclass of ndn::Tag
|
||||
* \note Tag can be removed even on a const tag host instance
|
||||
*/
|
||||
template<typename T>
|
||||
void
|
||||
@@ -65,20 +70,19 @@ template<typename T>
|
||||
shared_ptr<T>
|
||||
TagHost::getTag() const
|
||||
{
|
||||
static_assert(std::is_base_of<Tag, T>::value, "T must inherit from Tag");
|
||||
static_assert(std::is_convertible_v<T*, Tag*>, "T must inherit from ndn::Tag");
|
||||
|
||||
auto it = m_tags.find(T::getTypeId());
|
||||
if (it == m_tags.end()) {
|
||||
return nullptr;
|
||||
if (auto it = m_tags.find(T::getTypeId()); it != m_tags.end()) {
|
||||
return std::static_pointer_cast<T>(it->second);
|
||||
}
|
||||
return static_pointer_cast<T>(it->second);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
TagHost::setTag(shared_ptr<T> tag) const
|
||||
{
|
||||
static_assert(std::is_base_of<Tag, T>::value, "T must inherit from Tag");
|
||||
static_assert(std::is_convertible_v<T*, Tag*>, "T must inherit from ndn::Tag");
|
||||
|
||||
if (tag == nullptr) {
|
||||
m_tags.erase(T::getTypeId());
|
||||
@@ -97,4 +101,4 @@ TagHost::removeTag() const
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_DETAIL_TAG_HOST_HPP
|
||||
#endif // NDN_CXX_DETAIL_TAG_HOST_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -23,10 +23,37 @@
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
|
||||
namespace ndn {
|
||||
namespace encoding {
|
||||
namespace ndn::encoding {
|
||||
|
||||
namespace endian = boost::endian;
|
||||
// ---- empty ----
|
||||
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type)
|
||||
{
|
||||
size_t length = encoder.prependVarNumber(0);
|
||||
length += encoder.prependVarNumber(type);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
template size_t
|
||||
prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
|
||||
|
||||
template size_t
|
||||
prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
|
||||
|
||||
Block
|
||||
makeEmptyBlock(uint32_t type)
|
||||
{
|
||||
EncodingEstimator estimator;
|
||||
size_t totalLength = prependEmptyBlock(estimator, type);
|
||||
|
||||
EncodingBuffer encoder(totalLength, 0);
|
||||
prependEmptyBlock(encoder, type);
|
||||
|
||||
return encoder.block();
|
||||
}
|
||||
|
||||
// ---- non-negative integer ----
|
||||
|
||||
@@ -34,12 +61,11 @@ template<Tag TAG>
|
||||
size_t
|
||||
prependNonNegativeIntegerBlock(EncodingImpl<TAG>& encoder, uint32_t type, uint64_t value)
|
||||
{
|
||||
size_t valueLength = encoder.prependNonNegativeInteger(value);
|
||||
size_t totalLength = valueLength;
|
||||
totalLength += encoder.prependVarNumber(valueLength);
|
||||
totalLength += encoder.prependVarNumber(type);
|
||||
size_t length = encoder.prependNonNegativeInteger(value);
|
||||
length += encoder.prependVarNumber(length);
|
||||
length += encoder.prependVarNumber(type);
|
||||
|
||||
return totalLength;
|
||||
return length;
|
||||
}
|
||||
|
||||
template size_t
|
||||
@@ -67,63 +93,6 @@ readNonNegativeInteger(const Block& block)
|
||||
return tlv::readNonNegativeInteger(block.value_size(), begin, block.value_end());
|
||||
}
|
||||
|
||||
// ---- empty ----
|
||||
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type)
|
||||
{
|
||||
size_t totalLength = encoder.prependVarNumber(0);
|
||||
totalLength += encoder.prependVarNumber(type);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
template size_t
|
||||
prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
|
||||
|
||||
template size_t
|
||||
prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
|
||||
|
||||
Block
|
||||
makeEmptyBlock(uint32_t type)
|
||||
{
|
||||
EncodingEstimator estimator;
|
||||
size_t totalLength = prependEmptyBlock(estimator, type);
|
||||
|
||||
EncodingBuffer encoder(totalLength, 0);
|
||||
prependEmptyBlock(encoder, type);
|
||||
|
||||
return encoder.block();
|
||||
}
|
||||
|
||||
// ---- string ----
|
||||
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value)
|
||||
{
|
||||
return encoder.prependByteArrayBlock(type, reinterpret_cast<const uint8_t*>(value.data()), value.size());
|
||||
}
|
||||
|
||||
template size_t
|
||||
prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, const std::string&);
|
||||
|
||||
template size_t
|
||||
prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, const std::string&);
|
||||
|
||||
Block
|
||||
makeStringBlock(uint32_t type, const std::string& value)
|
||||
{
|
||||
return makeBinaryBlock(type, value.data(), value.size());
|
||||
}
|
||||
|
||||
std::string
|
||||
readString(const Block& block)
|
||||
{
|
||||
return std::string(reinterpret_cast<const char*>(block.value()), block.value_size());
|
||||
}
|
||||
|
||||
// ---- double ----
|
||||
|
||||
static_assert(std::numeric_limits<double>::is_iec559, "This code requires IEEE-754 doubles");
|
||||
@@ -134,8 +103,8 @@ prependDoubleBlock(EncodingImpl<TAG>& encoder, uint32_t type, double value)
|
||||
{
|
||||
uint64_t temp = 0;
|
||||
std::memcpy(&temp, &value, 8);
|
||||
endian::native_to_big_inplace(temp);
|
||||
return encoder.prependByteArrayBlock(type, reinterpret_cast<const uint8_t*>(&temp), 8);
|
||||
boost::endian::native_to_big_inplace(temp);
|
||||
return prependBinaryBlock(encoder, type, {reinterpret_cast<const uint8_t*>(&temp), 8});
|
||||
}
|
||||
|
||||
template size_t
|
||||
@@ -162,38 +131,80 @@ readDouble(const Block& block)
|
||||
if (block.value_size() != 8) {
|
||||
NDN_THROW(tlv::Error("Invalid length for double (must be 8)"));
|
||||
}
|
||||
|
||||
#if BOOST_VERSION >= 107100
|
||||
return endian::endian_load<double, 8, endian::order::big>(block.value());
|
||||
#else
|
||||
uint64_t temp = 0;
|
||||
std::memcpy(&temp, block.value(), 8);
|
||||
endian::big_to_native_inplace(temp);
|
||||
double d = 0;
|
||||
std::memcpy(&d, &temp, 8);
|
||||
return d;
|
||||
#endif
|
||||
return boost::endian::endian_load<double, 8, boost::endian::order::big>(block.value());
|
||||
}
|
||||
|
||||
// ---- binary ----
|
||||
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependBinaryBlock(EncodingImpl<TAG>& encoder, uint32_t type, span<const uint8_t> value)
|
||||
{
|
||||
size_t length = encoder.prependBytes(value);
|
||||
length += encoder.prependVarNumber(length);
|
||||
length += encoder.prependVarNumber(type);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
template size_t
|
||||
prependBinaryBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, span<const uint8_t>);
|
||||
|
||||
template size_t
|
||||
prependBinaryBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, span<const uint8_t>);
|
||||
|
||||
Block
|
||||
makeBinaryBlock(uint32_t type, const uint8_t* value, size_t length)
|
||||
makeBinaryBlock(uint32_t type, span<const uint8_t> value)
|
||||
{
|
||||
EncodingEstimator estimator;
|
||||
size_t totalLength = estimator.prependByteArrayBlock(type, value, length);
|
||||
size_t totalLength = prependBinaryBlock(estimator, type, value);
|
||||
|
||||
EncodingBuffer encoder(totalLength, 0);
|
||||
encoder.prependByteArrayBlock(type, value, length);
|
||||
prependBinaryBlock(encoder, type, value);
|
||||
|
||||
return encoder.block();
|
||||
}
|
||||
|
||||
Block
|
||||
makeBinaryBlock(uint32_t type, const char* value, size_t length)
|
||||
// ---- string ----
|
||||
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, std::string_view value)
|
||||
{
|
||||
return makeBinaryBlock(type, reinterpret_cast<const uint8_t*>(value), length);
|
||||
return prependBinaryBlock(encoder, type, {reinterpret_cast<const uint8_t*>(value.data()), value.size()});
|
||||
}
|
||||
|
||||
} // namespace encoding
|
||||
} // namespace ndn
|
||||
template size_t
|
||||
prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, std::string_view);
|
||||
|
||||
template size_t
|
||||
prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, std::string_view);
|
||||
|
||||
std::string
|
||||
readString(const Block& block)
|
||||
{
|
||||
return std::string(reinterpret_cast<const char*>(block.value()), block.value_size());
|
||||
}
|
||||
|
||||
// ---- block ----
|
||||
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependBlock(EncodingImpl<TAG>& encoder, const Block& block)
|
||||
{
|
||||
if (block.hasWire()) {
|
||||
return encoder.prependBytes(block);
|
||||
}
|
||||
else {
|
||||
// FIXME: blindly calling Block::value_bytes() is not safe if the value is not wire-encoded
|
||||
return prependBinaryBlock(encoder, block.type(), block.value_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
template size_t
|
||||
prependBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, const Block&);
|
||||
|
||||
template size_t
|
||||
prependBlock<EncoderTag>(EncodingImpl<EncoderTag>&, const Block&);
|
||||
|
||||
} // namespace ndn::encoding
|
||||
+209
-129
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,8 +19,8 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_ENCODING_BLOCK_HELPERS_HPP
|
||||
#define NDN_ENCODING_BLOCK_HELPERS_HPP
|
||||
#ifndef NDN_CXX_ENCODING_BLOCK_HELPERS_HPP
|
||||
#define NDN_CXX_ENCODING_BLOCK_HELPERS_HPP
|
||||
|
||||
#include "ndn-cxx/encoding/block.hpp"
|
||||
#include "ndn-cxx/encoding/encoding-buffer.hpp"
|
||||
@@ -29,6 +29,30 @@
|
||||
namespace ndn {
|
||||
namespace encoding {
|
||||
|
||||
/** @brief Prepend an empty TLV element.
|
||||
* @param encoder an EncodingBuffer or EncodingEstimator
|
||||
* @param type TLV-TYPE number
|
||||
* @details The TLV element has zero-length TLV-VALUE.
|
||||
* @sa makeEmptyBlock
|
||||
*/
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type);
|
||||
|
||||
extern template size_t
|
||||
prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
|
||||
|
||||
extern template size_t
|
||||
prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
|
||||
|
||||
/** @brief Create an empty TLV block.
|
||||
* @param type TLV-TYPE number
|
||||
* @return A TLV block with zero-length TLV-VALUE
|
||||
* @sa prependEmptyBlock
|
||||
*/
|
||||
Block
|
||||
makeEmptyBlock(uint32_t type);
|
||||
|
||||
/** @brief Prepend a TLV element containing a non-negative integer.
|
||||
* @param encoder an EncodingBuffer or EncodingEstimator
|
||||
* @param type TLV-TYPE number
|
||||
@@ -68,7 +92,7 @@ readNonNegativeInteger(const Block& block);
|
||||
* represented in R
|
||||
*/
|
||||
template<typename R>
|
||||
std::enable_if_t<std::is_integral<R>::value, R>
|
||||
std::enable_if_t<std::is_integral_v<R>, R>
|
||||
readNonNegativeIntegerAs(const Block& block)
|
||||
{
|
||||
uint64_t value = readNonNegativeInteger(block);
|
||||
@@ -87,68 +111,12 @@ readNonNegativeIntegerAs(const Block& block)
|
||||
* function may trigger unspecified behavior.
|
||||
*/
|
||||
template<typename R>
|
||||
std::enable_if_t<std::is_enum<R>::value, R>
|
||||
std::enable_if_t<std::is_enum_v<R>, R>
|
||||
readNonNegativeIntegerAs(const Block& block)
|
||||
{
|
||||
return static_cast<R>(readNonNegativeIntegerAs<std::underlying_type_t<R>>(block));
|
||||
}
|
||||
|
||||
/** @brief Prepend an empty TLV element.
|
||||
* @param encoder an EncodingBuffer or EncodingEstimator
|
||||
* @param type TLV-TYPE number
|
||||
* @details The TLV element has zero-length TLV-VALUE.
|
||||
* @sa makeEmptyBlock
|
||||
*/
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type);
|
||||
|
||||
extern template size_t
|
||||
prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
|
||||
|
||||
extern template size_t
|
||||
prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
|
||||
|
||||
/** @brief Create an empty TLV block.
|
||||
* @param type TLV-TYPE number
|
||||
* @return A TLV block with zero-length TLV-VALUE
|
||||
* @sa prependEmptyBlock
|
||||
*/
|
||||
Block
|
||||
makeEmptyBlock(uint32_t type);
|
||||
|
||||
/** @brief Prepend a TLV element containing a string.
|
||||
* @param encoder an EncodingBuffer or EncodingEstimator
|
||||
* @param type TLV-TYPE number
|
||||
* @param value string value, may contain NUL octets
|
||||
* @sa makeStringBlock, readString
|
||||
*/
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value);
|
||||
|
||||
extern template size_t
|
||||
prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, const std::string&);
|
||||
|
||||
extern template size_t
|
||||
prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, const std::string&);
|
||||
|
||||
/** @brief Create a TLV block containing a string.
|
||||
* @param type TLV-TYPE number
|
||||
* @param value string value, may contain NUL octets
|
||||
* @sa prependStringBlock, readString
|
||||
*/
|
||||
Block
|
||||
makeStringBlock(uint32_t type, const std::string& value);
|
||||
|
||||
/** @brief Read TLV-VALUE of a TLV element as a string.
|
||||
* @param block the TLV element
|
||||
* @return a string, may contain NUL octets
|
||||
* @sa prependStringBlock, makeStringBlock
|
||||
*/
|
||||
std::string
|
||||
readString(const Block& block);
|
||||
|
||||
/** @brief Prepend a TLV element containing an IEEE 754 double-precision floating-point number.
|
||||
* @param encoder an EncodingBuffer or EncodingEstimator
|
||||
* @param type TLV-TYPE number
|
||||
@@ -181,96 +149,165 @@ makeDoubleBlock(uint32_t type, double value);
|
||||
double
|
||||
readDouble(const Block& block);
|
||||
|
||||
/** @brief Create a TLV block copying TLV-VALUE from raw buffer.
|
||||
* @param type TLV-TYPE number
|
||||
* @param value raw buffer as TLV-VALUE
|
||||
* @param length length of value buffer
|
||||
* @sa Encoder::prependByteArrayBlock
|
||||
/**
|
||||
* @brief Prepend a TLV element containing a sequence of raw bytes.
|
||||
* @param encoder an EncodingBuffer or EncodingEstimator
|
||||
* @param type TLV-TYPE number
|
||||
* @param value range of bytes to use as TLV-VALUE
|
||||
* @sa makeBinaryBlock
|
||||
*/
|
||||
Block
|
||||
makeBinaryBlock(uint32_t type, const uint8_t* value, size_t length);
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependBinaryBlock(EncodingImpl<TAG>& encoder, uint32_t type, span<const uint8_t> value);
|
||||
|
||||
/** @brief Create a TLV block copying TLV-VALUE from raw buffer.
|
||||
* @param type TLV-TYPE number
|
||||
* @param value raw buffer as TLV-VALUE
|
||||
* @param length length of value buffer
|
||||
* @sa Encoder::prependByteArrayBlock
|
||||
extern template size_t
|
||||
prependBinaryBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, span<const uint8_t>);
|
||||
|
||||
extern template size_t
|
||||
prependBinaryBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, span<const uint8_t>);
|
||||
|
||||
/**
|
||||
* @brief Create a TLV block copying the TLV-VALUE from a byte range.
|
||||
* @param type TLV-TYPE number
|
||||
* @param value range of bytes to use as TLV-VALUE
|
||||
* @sa prependBinaryBlock
|
||||
*/
|
||||
Block
|
||||
makeBinaryBlock(uint32_t type, const char* value, size_t length);
|
||||
makeBinaryBlock(uint32_t type, span<const uint8_t> value);
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** @brief Create a binary block copying from RandomAccessIterator.
|
||||
/**
|
||||
* @brief Create a binary block copying from RandomAccessIterator.
|
||||
*/
|
||||
template<class Iterator>
|
||||
class BinaryBlockFast
|
||||
Block
|
||||
makeBinaryBlockFast(uint32_t type, Iterator first, Iterator last)
|
||||
{
|
||||
public:
|
||||
BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<Iterator>));
|
||||
|
||||
static Block
|
||||
makeBlock(uint32_t type, Iterator first, Iterator last)
|
||||
{
|
||||
EncodingEstimator estimator;
|
||||
size_t valueLength = last - first;
|
||||
size_t totalLength = valueLength;
|
||||
totalLength += estimator.prependVarNumber(valueLength);
|
||||
totalLength += estimator.prependVarNumber(type);
|
||||
EncodingEstimator estimator;
|
||||
size_t valueLength = last - first;
|
||||
size_t totalLength = valueLength;
|
||||
totalLength += estimator.prependVarNumber(valueLength);
|
||||
totalLength += estimator.prependVarNumber(type);
|
||||
|
||||
EncodingBuffer encoder(totalLength, 0);
|
||||
encoder.prependRange(first, last);
|
||||
encoder.prependVarNumber(valueLength);
|
||||
encoder.prependVarNumber(type);
|
||||
EncodingBuffer encoder(totalLength, 0);
|
||||
encoder.prependRange(first, last);
|
||||
encoder.prependVarNumber(valueLength);
|
||||
encoder.prependVarNumber(type);
|
||||
|
||||
return encoder.block();
|
||||
}
|
||||
};
|
||||
return encoder.block();
|
||||
}
|
||||
|
||||
/** @brief Create a binary block copying from generic InputIterator.
|
||||
/**
|
||||
* @brief Create a binary block copying from generic InputIterator.
|
||||
*/
|
||||
template<class Iterator>
|
||||
class BinaryBlockSlow
|
||||
Block
|
||||
makeBinaryBlockSlow(uint32_t type, Iterator first, Iterator last)
|
||||
{
|
||||
public:
|
||||
BOOST_CONCEPT_ASSERT((boost::InputIterator<Iterator>));
|
||||
|
||||
static Block
|
||||
makeBlock(uint32_t type, Iterator first, Iterator last)
|
||||
{
|
||||
// reserve 4 bytes in front (common for 1(type)-3(length) encoding
|
||||
// Actual size will be adjusted as necessary by the encoder
|
||||
EncodingBuffer encoder(4, 4);
|
||||
size_t valueLength = encoder.appendRange(first, last);
|
||||
encoder.prependVarNumber(valueLength);
|
||||
encoder.prependVarNumber(type);
|
||||
// Reserve 4 bytes in front, common for 1(type)-3(length) encoding.
|
||||
// Actual size will be adjusted as necessary by the encoder.
|
||||
EncodingBuffer encoder(4, 4);
|
||||
size_t valueLength = encoder.appendRange(first, last);
|
||||
encoder.prependVarNumber(valueLength);
|
||||
encoder.prependVarNumber(type);
|
||||
|
||||
return encoder.block();
|
||||
}
|
||||
};
|
||||
return encoder.block();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/** @brief Create a TLV block copying TLV-VALUE from iterators.
|
||||
* @tparam Iterator an InputIterator dereferencable to an 1-octet type; faster implementation is
|
||||
* available for RandomAccessIterator
|
||||
* @param type TLV-TYPE number
|
||||
* @param first begin iterator
|
||||
* @param last past-the-end iterator
|
||||
/**
|
||||
* @brief Create a TLV block copying TLV-VALUE from iterators.
|
||||
* @tparam Iterator an InputIterator dereferenceable to a 1-octet type; a faster implementation is
|
||||
* automatically selected for RandomAccessIterator
|
||||
* @param type TLV-TYPE number
|
||||
* @param first begin iterator
|
||||
* @param last past-the-end iterator
|
||||
* @sa prependBinaryBlock
|
||||
*/
|
||||
template<class Iterator>
|
||||
Block
|
||||
makeBinaryBlock(uint32_t type, Iterator first, Iterator last)
|
||||
{
|
||||
using BinaryBlockHelper = std::conditional_t<
|
||||
std::is_base_of<std::random_access_iterator_tag,
|
||||
typename std::iterator_traits<Iterator>::iterator_category>::value,
|
||||
detail::BinaryBlockFast<Iterator>,
|
||||
detail::BinaryBlockSlow<Iterator>>;
|
||||
|
||||
return BinaryBlockHelper::makeBlock(type, first, last);
|
||||
if constexpr (std::is_base_of_v<std::random_access_iterator_tag,
|
||||
typename std::iterator_traits<Iterator>::iterator_category>)
|
||||
return detail::makeBinaryBlockFast(type, first, last);
|
||||
else
|
||||
return detail::makeBinaryBlockSlow(type, first, last);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a TLV block copying the TLV-VALUE from a char buffer.
|
||||
* @param type TLV-TYPE number
|
||||
* @param value raw buffer as TLV-VALUE
|
||||
* @param length length of value buffer
|
||||
* @deprecated Use makeStringBlock()
|
||||
*/
|
||||
[[deprecated("use makeStringBlock()")]]
|
||||
inline Block
|
||||
makeBinaryBlock(uint32_t type, const char* value, size_t length)
|
||||
{
|
||||
return makeBinaryBlock(type, {reinterpret_cast<const uint8_t*>(value), length});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend a TLV element containing a string.
|
||||
* @param encoder an EncodingBuffer or EncodingEstimator
|
||||
* @param type TLV-TYPE number
|
||||
* @param value string value, may contain NUL octets
|
||||
* @sa makeStringBlock, readString
|
||||
*/
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, std::string_view value);
|
||||
|
||||
extern template size_t
|
||||
prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, std::string_view);
|
||||
|
||||
extern template size_t
|
||||
prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, std::string_view);
|
||||
|
||||
/**
|
||||
* @brief Create a TLV block containing a string.
|
||||
* @param type TLV-TYPE number
|
||||
* @param value string value, may contain NUL octets
|
||||
* @sa prependStringBlock, readString
|
||||
*/
|
||||
inline Block
|
||||
makeStringBlock(uint32_t type, std::string_view value)
|
||||
{
|
||||
return makeBinaryBlock(type, {reinterpret_cast<const uint8_t*>(value.data()), value.size()});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the TLV-VALUE of a TLV element as a string.
|
||||
* @param block the TLV element
|
||||
* @return a string, may contain NUL octets
|
||||
* @sa prependStringBlock, makeStringBlock
|
||||
*/
|
||||
std::string
|
||||
readString(const Block& block);
|
||||
|
||||
/**
|
||||
* @brief Prepend a TLV element.
|
||||
* @param encoder an EncodingBuffer or EncodingEstimator
|
||||
* @param block the TLV element
|
||||
*/
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependBlock(EncodingImpl<TAG>& encoder, const Block& block);
|
||||
|
||||
extern template size_t
|
||||
prependBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, const Block&);
|
||||
|
||||
extern template size_t
|
||||
prependBlock<EncoderTag>(EncodingImpl<EncoderTag>&, const Block&);
|
||||
|
||||
/** @brief Prepend a TLV element containing a nested TLV element.
|
||||
* @tparam U type that satisfies WireEncodableWithEncodingBuffer concept
|
||||
* @param encoder an EncodingBuffer or EncodingEstimator
|
||||
@@ -284,12 +321,10 @@ prependNestedBlock(EncodingImpl<TAG>& encoder, uint32_t type, const U& value)
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<U>));
|
||||
|
||||
size_t valueLength = value.wireEncode(encoder);
|
||||
size_t totalLength = valueLength;
|
||||
totalLength += encoder.prependVarNumber(valueLength);
|
||||
totalLength += encoder.prependVarNumber(type);
|
||||
|
||||
return totalLength;
|
||||
size_t length = value.wireEncode(encoder);
|
||||
length += encoder.prependVarNumber(length);
|
||||
length += encoder.prependVarNumber(type);
|
||||
return length;
|
||||
}
|
||||
|
||||
/** @brief Create a TLV block containing a nested TLV element.
|
||||
@@ -307,21 +342,66 @@ makeNestedBlock(uint32_t type, const U& value)
|
||||
|
||||
EncodingBuffer encoder(totalLength, 0);
|
||||
prependNestedBlock(encoder, type, value);
|
||||
return encoder.block();
|
||||
}
|
||||
|
||||
/** @brief Prepend a TLV element containing a sequence of nested TLV elements.
|
||||
* @tparam I bidirectional iterator to a type that satisfies WireEncodableWithEncodingBuffer concept
|
||||
* @param encoder an EncodingBuffer or EncodingEstimator
|
||||
* @param type TLV-TYPE number for outer TLV element
|
||||
* @param first begin iterator to inner TLV elements
|
||||
* @param last past-end iterator to inner TLV elements
|
||||
* @sa makeNestedBlock
|
||||
*/
|
||||
template<Tag TAG, class I>
|
||||
size_t
|
||||
prependNestedBlock(EncodingImpl<TAG>& encoder, uint32_t type, I first, I last)
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<typename std::iterator_traits<I>::value_type>));
|
||||
|
||||
auto rfirst = std::make_reverse_iterator(last);
|
||||
auto rlast = std::make_reverse_iterator(first);
|
||||
|
||||
size_t length = 0;
|
||||
for (auto i = rfirst; i != rlast; ++i) {
|
||||
length += i->wireEncode(encoder);
|
||||
}
|
||||
|
||||
length += encoder.prependVarNumber(length);
|
||||
length += encoder.prependVarNumber(type);
|
||||
return length;
|
||||
}
|
||||
|
||||
/** @brief Create a TLV block containing a sequence of nested TLV elements.
|
||||
* @tparam I bidirectional iterator to a type that satisfies WireEncodableWithEncodingBuffer concept
|
||||
* @param type TLV-TYPE number for outer TLV element
|
||||
* @param first begin iterator to inner TLV elements
|
||||
* @param last past-end iterator to inner TLV elements
|
||||
* @sa prependNestedBlock
|
||||
*/
|
||||
template<class I>
|
||||
Block
|
||||
makeNestedBlock(uint32_t type, I first, I last)
|
||||
{
|
||||
EncodingEstimator estimator;
|
||||
size_t totalLength = prependNestedBlock(estimator, type, first, last);
|
||||
|
||||
EncodingBuffer encoder(totalLength, 0);
|
||||
prependNestedBlock(encoder, type, first, last);
|
||||
return encoder.block();
|
||||
}
|
||||
|
||||
} // namespace encoding
|
||||
|
||||
using encoding::makeEmptyBlock;
|
||||
using encoding::makeNonNegativeIntegerBlock;
|
||||
using encoding::readNonNegativeInteger;
|
||||
using encoding::readNonNegativeIntegerAs;
|
||||
using encoding::makeEmptyBlock;
|
||||
using encoding::makeBinaryBlock;
|
||||
using encoding::makeStringBlock;
|
||||
using encoding::readString;
|
||||
using encoding::makeBinaryBlock;
|
||||
using encoding::makeNestedBlock;
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_ENCODING_BLOCK_HELPERS_HPP
|
||||
#endif // NDN_CXX_ENCODING_BLOCK_HELPERS_HPP
|
||||
+143
-132
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -25,19 +25,22 @@
|
||||
#include "ndn-cxx/encoding/buffer-stream.hpp"
|
||||
#include "ndn-cxx/encoding/encoding-buffer.hpp"
|
||||
#include "ndn-cxx/encoding/tlv.hpp"
|
||||
#include "ndn-cxx/security/transform.hpp"
|
||||
#include "ndn-cxx/security/transform/hex-decode.hpp"
|
||||
#include "ndn-cxx/security/transform/step-source.hpp"
|
||||
#include "ndn-cxx/security/transform/stream-sink.hpp"
|
||||
#include "ndn-cxx/util/ostream-joiner.hpp"
|
||||
#include "ndn-cxx/util/scope.hpp"
|
||||
#include "ndn-cxx/util/string-helper.hpp"
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
namespace ndn {
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Block>));
|
||||
|
||||
const size_t MAX_SIZE_OF_BLOCK_FROM_STREAM = MAX_NDN_PACKET_SIZE;
|
||||
constexpr size_t MAX_SIZE_OF_BLOCK_FROM_STREAM = MAX_NDN_PACKET_SIZE;
|
||||
|
||||
// ---- constructor, creation, assignment ----
|
||||
|
||||
@@ -48,6 +51,30 @@ Block::Block(const Block&) = default;
|
||||
Block&
|
||||
Block::operator=(const Block&) = default;
|
||||
|
||||
Block::Block(span<const uint8_t> buffer)
|
||||
{
|
||||
auto pos = buffer.begin();
|
||||
const auto end = buffer.end();
|
||||
|
||||
m_type = tlv::readType(pos, end);
|
||||
uint64_t length = tlv::readVarNumber(pos, end);
|
||||
// pos now points to TLV-VALUE
|
||||
|
||||
BOOST_ASSERT(pos <= end);
|
||||
if (length > static_cast<uint64_t>(std::distance(pos, end))) {
|
||||
NDN_THROW(Error("Not enough bytes in the buffer to fully parse TLV"));
|
||||
}
|
||||
std::advance(pos, length);
|
||||
// pos now points to the end of the TLV
|
||||
|
||||
m_buffer = std::make_shared<Buffer>(buffer.begin(), pos);
|
||||
m_begin = m_buffer->begin();
|
||||
m_end = m_buffer->end();
|
||||
m_valueBegin = std::prev(m_end, length);
|
||||
m_valueEnd = m_buffer->end();
|
||||
m_size = m_buffer->size();
|
||||
}
|
||||
|
||||
Block::Block(const EncodingBuffer& buffer)
|
||||
: Block(buffer.getBuffer(), buffer.begin(), buffer.end(), true)
|
||||
{
|
||||
@@ -65,9 +92,9 @@ Block::Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_
|
||||
, m_end(end)
|
||||
, m_valueBegin(m_begin)
|
||||
, m_valueEnd(m_end)
|
||||
, m_size(m_end - m_begin)
|
||||
, m_size(static_cast<size_t>(std::distance(m_begin, m_end)))
|
||||
{
|
||||
if (m_buffer->size() == 0) {
|
||||
if (m_buffer->empty()) {
|
||||
NDN_THROW(std::invalid_argument("Buffer is empty"));
|
||||
}
|
||||
|
||||
@@ -87,7 +114,7 @@ Block::Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_
|
||||
}
|
||||
}
|
||||
|
||||
Block::Block(const Block& block, Buffer::const_iterator begin, Buffer::const_iterator end,
|
||||
Block::Block(const Block& block, Block::const_iterator begin, Block::const_iterator end,
|
||||
bool verifyLength)
|
||||
: Block(block.m_buffer, begin, end, verifyLength)
|
||||
{
|
||||
@@ -102,34 +129,10 @@ Block::Block(ConstBufferPtr buffer, uint32_t type,
|
||||
, m_valueBegin(valueBegin)
|
||||
, m_valueEnd(valueEnd)
|
||||
, m_type(type)
|
||||
, m_size(m_end - m_begin)
|
||||
, m_size(static_cast<size_t>(std::distance(m_begin, m_end)))
|
||||
{
|
||||
}
|
||||
|
||||
Block::Block(const uint8_t* buf, size_t bufSize)
|
||||
{
|
||||
const uint8_t* pos = buf;
|
||||
const uint8_t* const end = buf + bufSize;
|
||||
|
||||
m_type = tlv::readType(pos, end);
|
||||
uint64_t length = tlv::readVarNumber(pos, end);
|
||||
// pos now points to TLV-VALUE
|
||||
|
||||
BOOST_ASSERT(pos <= end);
|
||||
if (length > static_cast<uint64_t>(end - pos)) {
|
||||
NDN_THROW(Error("Not enough bytes in the buffer to fully parse TLV"));
|
||||
}
|
||||
|
||||
BOOST_ASSERT(pos > buf);
|
||||
uint64_t typeLengthSize = static_cast<uint64_t>(pos - buf);
|
||||
m_size = typeLengthSize + length;
|
||||
|
||||
m_buffer = make_shared<Buffer>(buf, m_size);
|
||||
m_begin = m_buffer->begin();
|
||||
m_end = m_valueEnd = m_buffer->end();
|
||||
m_valueBegin = m_begin + typeLengthSize;
|
||||
}
|
||||
|
||||
Block::Block(uint32_t type)
|
||||
: m_type(type)
|
||||
, m_size(tlv::sizeOfVarNumber(m_type) + tlv::sizeOfVarNumber(0))
|
||||
@@ -158,6 +161,63 @@ Block::Block(uint32_t type, const Block& value)
|
||||
m_size = tlv::sizeOfVarNumber(m_type) + tlv::sizeOfVarNumber(value_size()) + value_size();
|
||||
}
|
||||
|
||||
std::tuple<bool, Block>
|
||||
Block::fromBuffer(ConstBufferPtr buffer, size_t offset)
|
||||
{
|
||||
auto begin = std::next(buffer->begin(), offset);
|
||||
auto pos = begin;
|
||||
const auto end = buffer->end();
|
||||
|
||||
uint32_t type = 0;
|
||||
bool isOk = tlv::readType(pos, end, type);
|
||||
if (!isOk) {
|
||||
return {false, {}};
|
||||
}
|
||||
|
||||
uint64_t length = 0;
|
||||
isOk = tlv::readVarNumber(pos, end, length);
|
||||
if (!isOk) {
|
||||
return {false, {}};
|
||||
}
|
||||
// pos now points to TLV-VALUE
|
||||
|
||||
BOOST_ASSERT(pos <= end);
|
||||
if (length > static_cast<uint64_t>(std::distance(pos, end))) {
|
||||
return {false, {}};
|
||||
}
|
||||
|
||||
return {true, Block(std::move(buffer), type, begin, pos + length, pos, pos + length)};
|
||||
}
|
||||
|
||||
std::tuple<bool, Block>
|
||||
Block::fromBuffer(span<const uint8_t> buffer)
|
||||
{
|
||||
auto pos = buffer.begin();
|
||||
const auto end = buffer.end();
|
||||
|
||||
uint32_t type = 0;
|
||||
bool isOk = tlv::readType(pos, end, type);
|
||||
if (!isOk) {
|
||||
return {false, {}};
|
||||
}
|
||||
uint64_t length = 0;
|
||||
isOk = tlv::readVarNumber(pos, end, length);
|
||||
if (!isOk) {
|
||||
return {false, {}};
|
||||
}
|
||||
// pos now points to TLV-VALUE
|
||||
|
||||
BOOST_ASSERT(pos <= end);
|
||||
if (length > static_cast<uint64_t>(std::distance(pos, end))) {
|
||||
return {false, {}};
|
||||
}
|
||||
std::advance(pos, length);
|
||||
// pos now points to the end of the TLV
|
||||
|
||||
auto b = std::make_shared<Buffer>(buffer.begin(), pos);
|
||||
return {true, Block(b, type, b->begin(), b->end(), std::prev(b->end(), length), b->end())};
|
||||
}
|
||||
|
||||
Block
|
||||
Block::fromStream(std::istream& is)
|
||||
{
|
||||
@@ -176,7 +236,7 @@ Block::fromStream(std::istream& is)
|
||||
}
|
||||
|
||||
EncodingBuffer eb(tlSize + length, length);
|
||||
uint8_t* valueBuf = eb.buf();
|
||||
uint8_t* valueBuf = eb.data();
|
||||
is.read(reinterpret_cast<char*>(valueBuf), length);
|
||||
if (length != static_cast<uint64_t>(is.gcount())) {
|
||||
NDN_THROW(Error("Not enough bytes from stream to fully parse TLV"));
|
||||
@@ -190,60 +250,6 @@ Block::fromStream(std::istream& is)
|
||||
return Block(eb.getBuffer());
|
||||
}
|
||||
|
||||
std::tuple<bool, Block>
|
||||
Block::fromBuffer(ConstBufferPtr buffer, size_t offset)
|
||||
{
|
||||
auto begin = buffer->begin() + offset;
|
||||
auto pos = begin;
|
||||
|
||||
uint32_t type = 0;
|
||||
bool isOk = tlv::readType(pos, buffer->end(), type);
|
||||
if (!isOk) {
|
||||
return std::make_tuple(false, Block());
|
||||
}
|
||||
|
||||
uint64_t length = 0;
|
||||
isOk = tlv::readVarNumber(pos, buffer->end(), length);
|
||||
if (!isOk) {
|
||||
return std::make_tuple(false, Block());
|
||||
}
|
||||
// pos now points to TLV-VALUE
|
||||
|
||||
if (length > static_cast<uint64_t>(buffer->end() - pos)) {
|
||||
return std::make_tuple(false, Block());
|
||||
}
|
||||
|
||||
return std::make_tuple(true, Block(std::move(buffer), type, begin, pos + length, pos, pos + length));
|
||||
}
|
||||
|
||||
std::tuple<bool, Block>
|
||||
Block::fromBuffer(const uint8_t* buf, size_t bufSize)
|
||||
{
|
||||
const uint8_t* pos = buf;
|
||||
const uint8_t* const end = buf + bufSize;
|
||||
|
||||
uint32_t type = 0;
|
||||
bool isOk = tlv::readType(pos, end, type);
|
||||
if (!isOk) {
|
||||
return std::make_tuple(false, Block());
|
||||
}
|
||||
uint64_t length = 0;
|
||||
isOk = tlv::readVarNumber(pos, end, length);
|
||||
if (!isOk) {
|
||||
return std::make_tuple(false, Block());
|
||||
}
|
||||
// pos now points to TLV-VALUE
|
||||
|
||||
if (length > static_cast<uint64_t>(end - pos)) {
|
||||
return std::make_tuple(false, Block());
|
||||
}
|
||||
|
||||
size_t typeLengthSize = pos - buf;
|
||||
auto b = make_shared<Buffer>(buf, pos + length);
|
||||
return std::make_tuple(true, Block(b, type, b->begin(), b->end(),
|
||||
b->begin() + typeLengthSize, b->end()));
|
||||
}
|
||||
|
||||
// ---- wire format ----
|
||||
|
||||
void
|
||||
@@ -259,7 +265,7 @@ Block::resetWire() noexcept
|
||||
m_begin = m_end = m_valueBegin = m_valueEnd = {};
|
||||
}
|
||||
|
||||
Buffer::const_iterator
|
||||
Block::const_iterator
|
||||
Block::begin() const
|
||||
{
|
||||
if (!hasWire())
|
||||
@@ -268,7 +274,7 @@ Block::begin() const
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
Buffer::const_iterator
|
||||
Block::const_iterator
|
||||
Block::end() const
|
||||
{
|
||||
if (!hasWire())
|
||||
@@ -278,7 +284,7 @@ Block::end() const
|
||||
}
|
||||
|
||||
const uint8_t*
|
||||
Block::wire() const
|
||||
Block::data() const
|
||||
{
|
||||
if (!hasWire())
|
||||
NDN_THROW(Error("Underlying wire buffer is empty"));
|
||||
@@ -301,20 +307,15 @@ Block::size() const
|
||||
const uint8_t*
|
||||
Block::value() const noexcept
|
||||
{
|
||||
return hasValue() ? &*m_valueBegin : nullptr;
|
||||
}
|
||||
|
||||
size_t
|
||||
Block::value_size() const noexcept
|
||||
{
|
||||
return hasValue() ? static_cast<size_t>(m_valueEnd - m_valueBegin) : 0;
|
||||
return value_size() > 0 ? &*m_valueBegin : nullptr;
|
||||
}
|
||||
|
||||
Block
|
||||
Block::blockFromValue() const
|
||||
{
|
||||
if (!hasValue())
|
||||
NDN_THROW(Error("Block has no TLV-VALUE"));
|
||||
if (value_size() == 0) {
|
||||
NDN_THROW(Error("Cannot construct block from empty TLV-VALUE"));
|
||||
}
|
||||
|
||||
return Block(*this, m_valueBegin, m_valueEnd, true);
|
||||
}
|
||||
@@ -327,12 +328,11 @@ Block::parse() const
|
||||
if (!m_elements.empty() || value_size() == 0)
|
||||
return;
|
||||
|
||||
Buffer::const_iterator begin = value_begin();
|
||||
Buffer::const_iterator end = value_end();
|
||||
auto begin = value_begin();
|
||||
auto end = value_end();
|
||||
|
||||
while (begin != end) {
|
||||
Buffer::const_iterator pos = begin;
|
||||
|
||||
auto pos = begin;
|
||||
uint32_t type = tlv::readType(pos, end);
|
||||
uint64_t length = tlv::readVarNumber(pos, end);
|
||||
if (length > static_cast<uint64_t>(end - pos)) {
|
||||
@@ -342,7 +342,7 @@ Block::parse() const
|
||||
}
|
||||
// pos now points to TLV-VALUE of sub element
|
||||
|
||||
Buffer::const_iterator subEnd = pos + length;
|
||||
auto subEnd = std::next(pos, length);
|
||||
m_elements.emplace_back(m_buffer, type, begin, subEnd, pos, subEnd);
|
||||
|
||||
begin = subEnd;
|
||||
@@ -413,13 +413,12 @@ Block::encode(EncodingBuffer& encoder)
|
||||
const Block&
|
||||
Block::get(uint32_t type) const
|
||||
{
|
||||
auto it = this->find(type);
|
||||
if (it != m_elements.end()) {
|
||||
if (auto it = find(type); it != m_elements.end()) {
|
||||
return *it;
|
||||
}
|
||||
|
||||
NDN_THROW(Error("No sub-element of type " + to_string(type) +
|
||||
" found in block of type " + to_string(m_type)));
|
||||
NDN_THROW(Error("No sub-element of type " + std::to_string(type) +
|
||||
" found in block of type " + std::to_string(m_type)));
|
||||
}
|
||||
|
||||
Block::element_const_iterator
|
||||
@@ -460,6 +459,13 @@ Block::push_back(const Block& element)
|
||||
m_elements.push_back(element);
|
||||
}
|
||||
|
||||
void
|
||||
Block::push_back(Block&& element)
|
||||
{
|
||||
resetWire();
|
||||
m_elements.push_back(std::move(element));
|
||||
}
|
||||
|
||||
Block::element_iterator
|
||||
Block::insert(Block::element_const_iterator pos, const Block& element)
|
||||
{
|
||||
@@ -471,47 +477,50 @@ Block::insert(Block::element_const_iterator pos, const Block& element)
|
||||
|
||||
Block::operator boost::asio::const_buffer() const
|
||||
{
|
||||
return boost::asio::const_buffer(wire(), size());
|
||||
return {data(), size()};
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const Block& lhs, const Block& rhs)
|
||||
Block::equals(const Block& other) const noexcept
|
||||
{
|
||||
return lhs.type() == rhs.type() &&
|
||||
lhs.value_size() == rhs.value_size() &&
|
||||
(lhs.value_size() == 0 ||
|
||||
std::memcmp(lhs.value(), rhs.value(), lhs.value_size()) == 0);
|
||||
return type() == other.type() &&
|
||||
value_size() == other.value_size() &&
|
||||
(value_size() == 0 ||
|
||||
std::equal(value_begin(), value_end(), other.value_begin()));
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const Block& block)
|
||||
void
|
||||
Block::print(std::ostream& os) const
|
||||
{
|
||||
auto oldFmt = os.flags(std::ios_base::dec);
|
||||
auto oldFlags = os.flags(std::ios_base::dec);
|
||||
auto restoreFlags = make_scope_exit([&] {
|
||||
os.flags(oldFlags);
|
||||
});
|
||||
|
||||
if (!block.isValid()) {
|
||||
if (!isValid()) {
|
||||
os << "[invalid]";
|
||||
}
|
||||
else if (!block.m_elements.empty()) {
|
||||
else if (!m_elements.empty()) {
|
||||
EncodingEstimator estimator;
|
||||
size_t tlvLength = block.encodeValue(estimator);
|
||||
os << block.type() << '[' << tlvLength << "]={";
|
||||
std::copy(block.elements_begin(), block.elements_end(), make_ostream_joiner(os, ','));
|
||||
size_t tlvLength = encodeValue(estimator);
|
||||
os << type() << '[' << tlvLength << "]={";
|
||||
std::copy(elements_begin(), elements_end(), make_ostream_joiner(os, ','));
|
||||
os << '}';
|
||||
}
|
||||
else if (block.value_size() > 0) {
|
||||
os << block.type() << '[' << block.value_size() << "]=";
|
||||
printHex(os, block.value(), block.value_size(), true);
|
||||
else if (value_size() > 0) {
|
||||
os << type() << '[' << value_size() << "]=";
|
||||
printHex(os, value_bytes(), true);
|
||||
}
|
||||
else {
|
||||
os << block.type() << "[empty]";
|
||||
os << type() << "[empty]";
|
||||
}
|
||||
|
||||
os.flags(oldFmt);
|
||||
return os;
|
||||
}
|
||||
|
||||
inline namespace literals {
|
||||
inline namespace block_literals {
|
||||
|
||||
Block
|
||||
operator "" _block(const char* input, std::size_t len)
|
||||
operator ""_block(const char* input, std::size_t len)
|
||||
{
|
||||
namespace t = security::transform;
|
||||
t::StepSource ss;
|
||||
@@ -520,7 +529,7 @@ operator "" _block(const char* input, std::size_t len)
|
||||
|
||||
for (const char* end = input + len; input != end; ++input) {
|
||||
if (std::strchr("0123456789ABCDEF", *input) != nullptr) {
|
||||
ss.write(reinterpret_cast<const uint8_t*>(input), 1);
|
||||
ss.write({reinterpret_cast<const uint8_t*>(input), 1});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,4 +543,6 @@ operator "" _block(const char* input, std::size_t len)
|
||||
return Block(os.buf());
|
||||
}
|
||||
|
||||
} // inline namespace block_literals
|
||||
} // inline namespace literals
|
||||
} // namespace ndn
|
||||
+207
-124
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -27,21 +27,25 @@
|
||||
#include "ndn-cxx/encoding/buffer.hpp"
|
||||
#include "ndn-cxx/encoding/encoding-buffer-fwd.hpp"
|
||||
#include "ndn-cxx/encoding/tlv.hpp"
|
||||
#include "ndn-cxx/util/span.hpp"
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
namespace boost::asio {
|
||||
class const_buffer;
|
||||
} // namespace asio
|
||||
} // namespace boost
|
||||
} // namespace boost::asio
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** @brief Represents a TLV element of the NDN packet format.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/tlv.html#tlv-encoding
|
||||
/**
|
||||
* @brief Represents a TLV element of the NDN packet format.
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
|
||||
*/
|
||||
class Block
|
||||
class Block : private boost::equality_comparable<Block>
|
||||
{
|
||||
public:
|
||||
using value_type = Buffer::value_type;
|
||||
using const_iterator = Buffer::const_iterator;
|
||||
using element_container = std::vector<Block>;
|
||||
using element_iterator = element_container::iterator;
|
||||
using element_const_iterator = element_container::const_iterator;
|
||||
@@ -76,6 +80,15 @@ public: // construction, assignment
|
||||
Block&
|
||||
operator=(Block&&) noexcept;
|
||||
|
||||
/** @brief Parse Block from a byte range
|
||||
* @param buffer sequence of bytes containing a TLV element; the element must be found at
|
||||
* the beginning of the buffer but does not need to span the entire buffer
|
||||
* @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH exceeds the size of @p buffer
|
||||
* @note This constructor copies the TLV element octets to an internal buffer.
|
||||
*/
|
||||
explicit
|
||||
Block(span<const uint8_t> buffer);
|
||||
|
||||
/** @brief Parse Block from an EncodingBuffer
|
||||
* @param buffer an EncodingBuffer containing one TLV element
|
||||
* @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
|
||||
@@ -85,8 +98,8 @@ public: // construction, assignment
|
||||
|
||||
/** @brief Parse Block from a wire Buffer
|
||||
* @param buffer a Buffer containing one TLV element
|
||||
* @note This constructor takes shared ownership of @p buffer.
|
||||
* @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
|
||||
* @note This constructor takes shared ownership of @p buffer.
|
||||
*/
|
||||
explicit
|
||||
Block(const ConstBufferPtr& buffer);
|
||||
@@ -98,7 +111,6 @@ public: // construction, assignment
|
||||
* @param verifyLength if true, check TLV-LENGTH equals size of TLV-VALUE
|
||||
* @throw std::invalid_argument @p buffer is empty, or [@p begin,@p end) range is not within @p buffer
|
||||
* @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
|
||||
* @note This overload automatically detects TLV-TYPE and position of TLV-VALUE.
|
||||
*/
|
||||
Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_iterator end,
|
||||
bool verifyLength = true);
|
||||
@@ -111,7 +123,7 @@ public: // construction, assignment
|
||||
* @throw std::invalid_argument [@p begin,@p end) range is not within @p block
|
||||
* @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
|
||||
*/
|
||||
Block(const Block& block, Buffer::const_iterator begin, Buffer::const_iterator end,
|
||||
Block(const Block& block, Block::const_iterator begin, Block::const_iterator end,
|
||||
bool verifyLength = true);
|
||||
|
||||
/** @brief Create a Block from a wire Buffer without parsing
|
||||
@@ -126,14 +138,6 @@ public: // construction, assignment
|
||||
Buffer::const_iterator begin, Buffer::const_iterator end,
|
||||
Buffer::const_iterator valueBegin, Buffer::const_iterator valueEnd);
|
||||
|
||||
/** @brief Parse Block from a raw buffer
|
||||
* @param buf pointer to the first octet of a TLV element
|
||||
* @param bufSize size of the raw buffer; may be greater than the actual size of the TLV element
|
||||
* @throw tlv::Error Type-Length parsing fails, or size of TLV-VALUE exceeds @p bufSize
|
||||
* @note This overload copies the TLV element octets into an internal wire buffer.
|
||||
*/
|
||||
Block(const uint8_t* buf, size_t bufSize);
|
||||
|
||||
/** @brief Create a zero-length Block with the specified TLV-TYPE
|
||||
* @param type TLV-TYPE
|
||||
*/
|
||||
@@ -152,6 +156,25 @@ public: // construction, assignment
|
||||
*/
|
||||
Block(uint32_t type, const Block& value);
|
||||
|
||||
/** @brief Try to parse Block from a wire buffer
|
||||
* @param buffer a Buffer containing a TLV element at offset @p offset
|
||||
* @param offset begin position of the TLV element within @p buffer
|
||||
* @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
|
||||
* @note This function does not throw upon decoding failure.
|
||||
*/
|
||||
[[nodiscard]] static std::tuple<bool, Block>
|
||||
fromBuffer(ConstBufferPtr buffer, size_t offset = 0);
|
||||
|
||||
/** @brief Try to parse Block from a byte range
|
||||
* @param buffer sequence of bytes containing a TLV element; the element must be found at
|
||||
* the beginning of the buffer but does not need to span the entire buffer
|
||||
* @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
|
||||
* @note This overload copies the TLV element octets to an internal buffer.
|
||||
* @note This function does not throw upon decoding failure.
|
||||
*/
|
||||
[[nodiscard]] static std::tuple<bool, Block>
|
||||
fromBuffer(span<const uint8_t> buffer);
|
||||
|
||||
/** @brief Parse Block from an input stream
|
||||
* @throw tlv::Error TLV-LENGTH is zero or exceeds upper bound
|
||||
* @warning If decoding fails, bytes are still consumed from the input stream.
|
||||
@@ -159,25 +182,6 @@ public: // construction, assignment
|
||||
static Block
|
||||
fromStream(std::istream& is);
|
||||
|
||||
/** @brief Try to parse Block from a wire buffer
|
||||
* @param buffer a Buffer containing a TLV element at offset @p offset
|
||||
* @param offset begin position of the TLV element within @p buffer
|
||||
* @note This function does not throw upon decoding failure.
|
||||
* @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
|
||||
*/
|
||||
NDN_CXX_NODISCARD static std::tuple<bool, Block>
|
||||
fromBuffer(ConstBufferPtr buffer, size_t offset);
|
||||
|
||||
/** @brief Try to parse Block from a raw buffer
|
||||
* @param buf pointer to the first octet of a TLV element
|
||||
* @param bufSize size of the raw buffer; may be greater than the actual size of the TLV element
|
||||
* @note This function does not throw upon decoding failure.
|
||||
* @note This overload copies the TLV element octets into an internal wire buffer.
|
||||
* @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
|
||||
*/
|
||||
NDN_CXX_NODISCARD static std::tuple<bool, Block>
|
||||
fromBuffer(const uint8_t* buf, size_t bufSize);
|
||||
|
||||
public: // wire format
|
||||
/** @brief Check if the Block is valid
|
||||
*
|
||||
@@ -219,33 +223,48 @@ public: // wire format
|
||||
return m_buffer != nullptr && m_begin != m_end;
|
||||
}
|
||||
|
||||
/** @brief Get begin iterator of encoded wire
|
||||
* @pre `hasWire() == true`
|
||||
/**
|
||||
* @brief Returns an iterator to the beginning of the encoded wire.
|
||||
* @pre `hasWire() == true`
|
||||
*/
|
||||
Buffer::const_iterator
|
||||
const_iterator
|
||||
begin() const;
|
||||
|
||||
/** @brief Get end iterator of encoded wire
|
||||
* @pre `hasWire() == true`
|
||||
/**
|
||||
* @brief Returns an iterator past-the-end of the encoded wire.
|
||||
* @pre `hasWire() == true`
|
||||
*/
|
||||
Buffer::const_iterator
|
||||
const_iterator
|
||||
end() const;
|
||||
|
||||
/** @brief Return a raw pointer to the beginning of the encoded wire
|
||||
* @pre `hasWire() == true`
|
||||
* @sa value()
|
||||
*/
|
||||
const uint8_t*
|
||||
wire() const;
|
||||
|
||||
/** @brief Return the size of the encoded wire, i.e. of the whole TLV
|
||||
* @pre `isValid() == true`
|
||||
* @sa value_size()
|
||||
/**
|
||||
* @brief Returns the size of the encoded wire, i.e., of the whole TLV.
|
||||
* @pre `isValid() == true`
|
||||
* @sa value_size()
|
||||
*/
|
||||
size_t
|
||||
size() const;
|
||||
|
||||
/** @brief Get underlying buffer
|
||||
/**
|
||||
* @brief Returns a raw pointer to the beginning of the encoded wire, i.e., the whole TLV.
|
||||
* @pre `hasWire() == true`
|
||||
* @sa value()
|
||||
*/
|
||||
const uint8_t*
|
||||
data() const;
|
||||
|
||||
/**
|
||||
* @deprecated Use data()
|
||||
*/
|
||||
[[deprecated("use data()")]]
|
||||
const uint8_t*
|
||||
wire() const
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the underlying buffer.
|
||||
*/
|
||||
ConstBufferPtr
|
||||
getBuffer() const
|
||||
@@ -254,21 +273,23 @@ public: // wire format
|
||||
}
|
||||
|
||||
public: // type and value
|
||||
/** @brief Return the TLV-TYPE of the Block
|
||||
* @note This will return tlv::Invalid if isValid() is false.
|
||||
/**
|
||||
* @brief Return the TLV-TYPE of the Block.
|
||||
* @note This will return tlv::Invalid if isValid() is false.
|
||||
*/
|
||||
uint32_t
|
||||
type() const
|
||||
type() const noexcept
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
/** @brief Check if the Block has a non-empty TLV-VALUE
|
||||
/**
|
||||
* @brief Check if the Block has a non-empty TLV-VALUE.
|
||||
*
|
||||
* This property reflects whether the underlying buffer contains a TLV-VALUE. If this is false,
|
||||
* TLV-VALUE has zero-length. If this is true, TLV-VALUE may be zero-length.
|
||||
* This property reflects whether the underlying buffer contains a TLV-VALUE. If this is false,
|
||||
* TLV-VALUE has zero-length. If this is true, TLV-VALUE may be zero-length.
|
||||
*
|
||||
* @sa value_size()
|
||||
* @sa value_size()
|
||||
*/
|
||||
bool
|
||||
hasValue() const noexcept
|
||||
@@ -276,36 +297,59 @@ public: // type and value
|
||||
return m_buffer != nullptr;
|
||||
}
|
||||
|
||||
/** @brief Get begin iterator of TLV-VALUE
|
||||
* @pre `hasValue() == true`
|
||||
/**
|
||||
* @brief Get begin iterator of TLV-VALUE.
|
||||
* @pre `hasValue() == true`
|
||||
*/
|
||||
Buffer::const_iterator
|
||||
value_begin() const
|
||||
const_iterator
|
||||
value_begin() const noexcept
|
||||
{
|
||||
return m_valueBegin;
|
||||
}
|
||||
|
||||
/** @brief Get end iterator of TLV-VALUE
|
||||
* @pre `hasValue() == true`
|
||||
/**
|
||||
* @brief Get end iterator of TLV-VALUE.
|
||||
* @pre `hasValue() == true`
|
||||
*/
|
||||
Buffer::const_iterator
|
||||
value_end() const
|
||||
const_iterator
|
||||
value_end() const noexcept
|
||||
{
|
||||
return m_valueEnd;
|
||||
}
|
||||
|
||||
/** @brief Return a raw pointer to the beginning of TLV-VALUE
|
||||
* @sa wire()
|
||||
/**
|
||||
* @brief Return the size of TLV-VALUE, i.e., the TLV-LENGTH.
|
||||
* @sa size()
|
||||
*/
|
||||
size_t
|
||||
value_size() const noexcept
|
||||
{
|
||||
return hasValue() ? static_cast<size_t>(m_valueEnd - m_valueBegin) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return a read-only view of TLV-VALUE as a contiguous range of bytes.
|
||||
*/
|
||||
span<const uint8_t>
|
||||
value_bytes() const noexcept
|
||||
{
|
||||
if (hasValue())
|
||||
return {m_valueBegin, m_valueEnd};
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return a raw pointer to the beginning of TLV-VALUE.
|
||||
* @sa value_bytes(), data()
|
||||
*/
|
||||
const uint8_t*
|
||||
value() const noexcept;
|
||||
|
||||
/** @brief Return the size of TLV-VALUE, aka TLV-LENGTH
|
||||
* @sa size()
|
||||
/**
|
||||
* @brief Return a new Block constructed from the TLV-VALUE of this Block.
|
||||
* @pre `value_size() > 0`
|
||||
*/
|
||||
size_t
|
||||
value_size() const noexcept;
|
||||
|
||||
Block
|
||||
blockFromValue() const;
|
||||
|
||||
@@ -327,14 +371,14 @@ public: // sub-elements
|
||||
encode();
|
||||
|
||||
/** @brief Return the first sub-element of the specified TLV-TYPE
|
||||
* @pre parse() has been executed
|
||||
* @pre parse() has been called
|
||||
* @throw tlv::Error a sub-element of the specified type does not exist
|
||||
*/
|
||||
const Block&
|
||||
get(uint32_t type) const;
|
||||
|
||||
/** @brief Find the first sub-element of the specified TLV-TYPE
|
||||
* @pre parse() has been executed
|
||||
* @pre parse() has been called
|
||||
* @return iterator in elements() to the found sub-element, or elements_end() if no such
|
||||
* sub-element exists in elements()
|
||||
*/
|
||||
@@ -342,7 +386,7 @@ public: // sub-elements
|
||||
find(uint32_t type) const;
|
||||
|
||||
/** @brief Remove all sub-elements of the specified TLV-TYPE
|
||||
* @pre parse() has been executed
|
||||
* @pre parse() has been called
|
||||
* @post `find(type) == elements_end()`
|
||||
*/
|
||||
void
|
||||
@@ -358,11 +402,18 @@ public: // sub-elements
|
||||
element_iterator
|
||||
erase(element_const_iterator first, element_const_iterator last);
|
||||
|
||||
/** @brief Append a sub-element
|
||||
/**
|
||||
* @brief Append a sub-element.
|
||||
*/
|
||||
void
|
||||
push_back(const Block& element);
|
||||
|
||||
/**
|
||||
* @brief Append a sub-element.
|
||||
*/
|
||||
void
|
||||
push_back(Block&& element);
|
||||
|
||||
/** @brief Insert a sub-element
|
||||
* @param pos position of the new sub-element
|
||||
* @param element new sub-element to insert
|
||||
@@ -371,62 +422,110 @@ public: // sub-elements
|
||||
element_iterator
|
||||
insert(element_const_iterator pos, const Block& element);
|
||||
|
||||
/** @brief Get container of sub-elements
|
||||
* @pre parse() has been executed
|
||||
/**
|
||||
* @brief Get container of sub-elements.
|
||||
* @pre parse() has been called.
|
||||
*/
|
||||
const element_container&
|
||||
elements() const
|
||||
elements() const noexcept
|
||||
{
|
||||
return m_elements;
|
||||
}
|
||||
|
||||
/** @brief Equivalent to elements().begin()
|
||||
/**
|
||||
* @brief Equivalent to `elements().begin()`.
|
||||
*/
|
||||
element_const_iterator
|
||||
elements_begin() const
|
||||
elements_begin() const noexcept
|
||||
{
|
||||
return m_elements.begin();
|
||||
}
|
||||
|
||||
/** @brief Equivalent to elements().end()
|
||||
/**
|
||||
* @brief Equivalent to `elements().end()`.
|
||||
*/
|
||||
element_const_iterator
|
||||
elements_end() const
|
||||
elements_end() const noexcept
|
||||
{
|
||||
return m_elements.end();
|
||||
}
|
||||
|
||||
/** @brief Equivalent to elements().size()
|
||||
/**
|
||||
* @brief Equivalent to `elements().size()`.
|
||||
*/
|
||||
size_t
|
||||
elements_size() const
|
||||
elements_size() const noexcept
|
||||
{
|
||||
return m_elements.size();
|
||||
}
|
||||
|
||||
public: // misc
|
||||
/** @brief Implicit conversion to `boost::asio::const_buffer`
|
||||
/**
|
||||
* @brief Implicit conversion to `boost::asio::const_buffer`.
|
||||
*/
|
||||
operator boost::asio::const_buffer() const;
|
||||
|
||||
private:
|
||||
/** @brief Estimate Block size as if sub-elements are encoded into TLV-VALUE
|
||||
/**
|
||||
* @brief Estimate Block size as if sub-elements are encoded into TLV-VALUE.
|
||||
*/
|
||||
size_t
|
||||
encode(EncodingEstimator& estimator) const;
|
||||
|
||||
/** @brief Estimate TLV-LENGTH as if sub-elements are encoded into TLV-VALUE
|
||||
/**
|
||||
* @brief Estimate TLV-LENGTH as if sub-elements are encoded into TLV-VALUE.
|
||||
*/
|
||||
size_t
|
||||
encodeValue(EncodingEstimator& estimator) const;
|
||||
|
||||
/** @brief Encode sub-elements into TLV-VALUE and prepend Block to encoder
|
||||
* @post TLV-VALUE contains sub-elements from elements()
|
||||
* @post internal buffer and iterators point to Encoder's buffer
|
||||
/**
|
||||
* @brief Encode sub-elements into TLV-VALUE and prepend Block to encoder.
|
||||
* @post TLV-VALUE contains sub-elements from elements()
|
||||
* @post internal buffer and iterators point to Encoder's buffer
|
||||
*/
|
||||
size_t
|
||||
encode(EncodingBuffer& encoder);
|
||||
|
||||
/**
|
||||
* @brief Returns whether this Block has the same TLV-TYPE/TLV-LENGTH/TLV-VALUE as @p other.
|
||||
*/
|
||||
bool
|
||||
equals(const Block& other) const noexcept;
|
||||
|
||||
void
|
||||
print(std::ostream& os) const;
|
||||
|
||||
private: // non-member operators
|
||||
// NOTE: the following "hidden friend" operators are available via
|
||||
// argument-dependent lookup only and must be defined inline.
|
||||
// boost::equality_comparable provides != operator.
|
||||
|
||||
/**
|
||||
* @brief Compare whether two Blocks have the same TLV-TYPE, TLV-LENGTH, and TLV-VALUE.
|
||||
*/
|
||||
friend bool
|
||||
operator==(const Block& lhs, const Block& rhs) noexcept
|
||||
{
|
||||
return lhs.equals(rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Print @p block to @p os.
|
||||
*
|
||||
* Default-constructed Block is printed as: `[invalid]`.
|
||||
* Zero-length Block is printed as: `TT[empty]`, where TT is TLV-TYPE in decimal.
|
||||
* Non-zero-length Block on which parse() has not been called is printed as: `TT[LL]=VVVV`,
|
||||
* where LL is TLV-LENGTH in decimal, and VVVV is TLV-VALUE in hexadecimal.
|
||||
* Block on which parse() has been called is printed as: `TT[LL]={SUB,SUB}`,
|
||||
* where each SUB is a sub-element printed using this format.
|
||||
*/
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const Block& block)
|
||||
{
|
||||
block.print(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
protected:
|
||||
/** @brief Underlying buffer storing TLV-VALUE and possibly TLV-TYPE and TLV-LENGTH fields
|
||||
*
|
||||
@@ -445,29 +544,19 @@ protected:
|
||||
|
||||
uint32_t m_type = tlv::Invalid; ///< TLV-TYPE
|
||||
|
||||
/** @brief Total size including Type-Length-Value
|
||||
/**
|
||||
* @brief Total size including Type-Length-Value.
|
||||
*
|
||||
* This field is meaningful only if isValid() is true.
|
||||
* This field is meaningful only if isValid() is true.
|
||||
*/
|
||||
size_t m_size = 0;
|
||||
|
||||
/** @brief Contains the sub-elements
|
||||
/**
|
||||
* @brief Contains the sub-elements.
|
||||
*
|
||||
* This field is valid only if parse() has been executed.
|
||||
* This field is valid only if parse() has been called on the Block instance.
|
||||
*/
|
||||
mutable element_container m_elements;
|
||||
|
||||
/** @brief Print @p block to @p os.
|
||||
*
|
||||
* Default-constructed Block is printed as: `[invalid]`.
|
||||
* Zero-length Block is printed as: `TT[empty]`, where TT is TLV-TYPE in decimal.
|
||||
* Non-zero-length Block on which parse() has not been called is printed as: `TT[LL]=VVVV`,
|
||||
* where LL is TLV-LENGTH in decimal, and VVVV is TLV-VALUE in hexadecimal.
|
||||
* Block on which parse() has been called is printed as: `TT[LL]={SUB,SUB}`,
|
||||
* where each SUB is a sub-element printed using this format.
|
||||
*/
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const Block& block);
|
||||
};
|
||||
|
||||
inline
|
||||
@@ -476,16 +565,8 @@ Block::Block(Block&&) noexcept = default;
|
||||
inline Block&
|
||||
Block::operator=(Block&&) noexcept = default;
|
||||
|
||||
/** @brief Compare whether two Blocks have same TLV-TYPE, TLV-LENGTH, and TLV-VALUE
|
||||
*/
|
||||
bool
|
||||
operator==(const Block& lhs, const Block& rhs);
|
||||
|
||||
inline bool
|
||||
operator!=(const Block& lhs, const Block& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
inline namespace literals {
|
||||
inline namespace block_literals {
|
||||
|
||||
/** @brief Construct a Block from hexadecimal @p input.
|
||||
* @param input a string containing hexadecimal bytes and comments.
|
||||
@@ -494,15 +575,17 @@ operator!=(const Block& lhs, const Block& rhs)
|
||||
* @throw std::invalid_argument input is empty or has an odd number of hexadecimal digits.
|
||||
* @throw tlv::Error @p input cannot be parsed into a valid Block.
|
||||
*
|
||||
* Example
|
||||
* Example:
|
||||
* @code
|
||||
* Block nameBlock = "0706 080141 080142"_block;
|
||||
* Block nackBlock = "FD032005 reason(no-route)=FD03210196"_block;
|
||||
* @endcode
|
||||
*/
|
||||
Block
|
||||
operator "" _block(const char* input, std::size_t len);
|
||||
operator ""_block(const char* input, std::size_t len);
|
||||
|
||||
} // inline namespace block_literals
|
||||
} // inline namespace literals
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_CXX_ENCODING_BLOCK_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2022 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -24,13 +24,13 @@
|
||||
namespace ndn {
|
||||
namespace detail {
|
||||
|
||||
BufferAppendDevice::BufferAppendDevice(Buffer& container)
|
||||
BufferSink::BufferSink(Buffer& container)
|
||||
: m_container(container)
|
||||
{
|
||||
}
|
||||
|
||||
std::streamsize
|
||||
BufferAppendDevice::write(const char_type* s, std::streamsize n)
|
||||
BufferSink::write(const char_type* s, std::streamsize n)
|
||||
{
|
||||
m_container.insert(m_container.end(), s, s + n);
|
||||
return n;
|
||||
@@ -39,21 +39,27 @@ BufferAppendDevice::write(const char_type* s, std::streamsize n)
|
||||
} // namespace detail
|
||||
|
||||
OBufferStream::OBufferStream()
|
||||
: m_buffer(make_shared<Buffer>())
|
||||
, m_device(*m_buffer)
|
||||
: m_buffer(std::make_shared<Buffer>())
|
||||
{
|
||||
open(m_device);
|
||||
open(detail::BufferSink{*m_buffer});
|
||||
}
|
||||
|
||||
OBufferStream::~OBufferStream()
|
||||
OBufferStream::~OBufferStream() noexcept
|
||||
{
|
||||
close();
|
||||
try {
|
||||
close();
|
||||
}
|
||||
catch (...) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<Buffer>
|
||||
OBufferStream::buf()
|
||||
{
|
||||
flush();
|
||||
if (is_open()) {
|
||||
flush();
|
||||
}
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2022 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -21,70 +21,68 @@
|
||||
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
*/
|
||||
|
||||
#ifndef NDN_ENCODING_BUFFER_STREAM_HPP
|
||||
#define NDN_ENCODING_BUFFER_STREAM_HPP
|
||||
#ifndef NDN_CXX_ENCODING_BUFFER_STREAM_HPP
|
||||
#define NDN_CXX_ENCODING_BUFFER_STREAM_HPP
|
||||
|
||||
#include "ndn-cxx/encoding/buffer.hpp"
|
||||
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/concepts.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
|
||||
namespace ndn {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** @brief (implementation detail) a Boost.Iostreams.Sink which appends to an \p ndn::Buffer
|
||||
/**
|
||||
* @brief (implementation detail) A Boost.Iostreams.Sink that appends to a Buffer.
|
||||
*/
|
||||
class BufferAppendDevice
|
||||
class BufferSink : public boost::iostreams::sink
|
||||
{
|
||||
public:
|
||||
typedef char char_type;
|
||||
typedef boost::iostreams::sink_tag category;
|
||||
|
||||
explicit
|
||||
BufferAppendDevice(Buffer& container);
|
||||
BufferSink(Buffer& container);
|
||||
|
||||
std::streamsize
|
||||
write(const char_type* s, std::streamsize n);
|
||||
|
||||
protected:
|
||||
private:
|
||||
Buffer& m_container;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/** @brief implements an output stream that constructs \p ndn::Buffer
|
||||
/**
|
||||
* @brief An output stream that writes to a Buffer.
|
||||
*
|
||||
* The benefit of using stream interface is that it provides automatic buffering of
|
||||
* written data and eliminates (or reduces) overhead of resizing the underlying buffer
|
||||
* when writing small pieces of data.
|
||||
* The benefit of using stream interface is that it provides automatic buffering of
|
||||
* written data and eliminates (or reduces) overhead of resizing the underlying buffer
|
||||
* when writing small pieces of data.
|
||||
*
|
||||
* Usage example:
|
||||
* @code
|
||||
* OBufferStream obuf;
|
||||
* obuf.put(0);
|
||||
* obuf.write(anotherBuffer, anotherBufferSize);
|
||||
* shared_ptr<Buffer> buf = obuf.buf();
|
||||
* @endcode
|
||||
* Usage example:
|
||||
* @code
|
||||
* OBufferStream obuf;
|
||||
* obuf << "foo";
|
||||
* obuf.put(0);
|
||||
* obuf.write(anotherBuffer, anotherBufferSize);
|
||||
* std::shared_ptr<Buffer> buf = obuf.buf();
|
||||
* @endcode
|
||||
*/
|
||||
class OBufferStream : public boost::iostreams::stream<detail::BufferAppendDevice>
|
||||
class OBufferStream : public boost::iostreams::stream<detail::BufferSink>
|
||||
{
|
||||
public:
|
||||
OBufferStream();
|
||||
|
||||
~OBufferStream();
|
||||
~OBufferStream() noexcept override;
|
||||
|
||||
/**
|
||||
* Flush written data to the stream and return shared pointer to the underlying buffer
|
||||
* @brief Return a shared pointer to the underlying buffer.
|
||||
*/
|
||||
shared_ptr<Buffer>
|
||||
buf();
|
||||
|
||||
private:
|
||||
BufferPtr m_buffer;
|
||||
detail::BufferAppendDevice m_device;
|
||||
shared_ptr<Buffer> m_buffer;
|
||||
};
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_ENCODING_BUFFER_STREAM_HPP
|
||||
#endif // NDN_CXX_ENCODING_BUFFER_STREAM_HPP
|
||||
@@ -19,11 +19,16 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_CXX_SECURITY_V2_VALIDATOR_HPP
|
||||
#define NDN_CXX_SECURITY_V2_VALIDATOR_HPP
|
||||
#include "ndn-cxx/encoding/buffer.hpp"
|
||||
#include "ndn-cxx/util/string-helper.hpp"
|
||||
|
||||
#warning This file is deprecated, include <ndn-cxx/security/validator.hpp> instead
|
||||
namespace ndn {
|
||||
|
||||
#include "ndn-cxx/security/validator.hpp"
|
||||
std::ostream&
|
||||
boost_test_print_type(std::ostream& os, const Buffer& buf)
|
||||
{
|
||||
printHex(os, buf, false);
|
||||
return os;
|
||||
}
|
||||
|
||||
#endif // NDN_CXX_SECURITY_V2_VALIDATOR_HPP
|
||||
} // namespace ndn
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2021 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -21,11 +21,12 @@
|
||||
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
*/
|
||||
|
||||
#ifndef NDN_ENCODING_BUFFER_HPP
|
||||
#define NDN_ENCODING_BUFFER_HPP
|
||||
#ifndef NDN_CXX_ENCODING_BUFFER_HPP
|
||||
#define NDN_CXX_ENCODING_BUFFER_HPP
|
||||
|
||||
#include "ndn-cxx/detail/common.hpp"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <vector>
|
||||
|
||||
namespace ndn {
|
||||
@@ -91,6 +92,13 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief Creates a Buffer with the contents of an initializer list
|
||||
*/
|
||||
Buffer(std::initializer_list<uint8_t> il)
|
||||
: std::vector<uint8_t>(il)
|
||||
{
|
||||
}
|
||||
|
||||
/** @return pointer to the first byte of the buffer, cast to the requested type T
|
||||
*/
|
||||
template<class T>
|
||||
@@ -122,9 +130,14 @@ Buffer::Buffer(Buffer&&) noexcept = default;
|
||||
inline Buffer&
|
||||
Buffer::operator=(Buffer&&) noexcept = default;
|
||||
|
||||
/** \cond */
|
||||
std::ostream&
|
||||
boost_test_print_type(std::ostream&, const Buffer&);
|
||||
/** \endcond */
|
||||
|
||||
using BufferPtr = shared_ptr<Buffer>;
|
||||
using ConstBufferPtr = shared_ptr<const Buffer>;
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_ENCODING_BUFFER_HPP
|
||||
#endif // NDN_CXX_ENCODING_BUFFER_HPP
|
||||
+30
-102
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -23,8 +23,7 @@
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
|
||||
namespace ndn {
|
||||
namespace encoding {
|
||||
namespace ndn::encoding {
|
||||
|
||||
namespace endian = boost::endian;
|
||||
|
||||
@@ -35,7 +34,7 @@ Encoder::Encoder(size_t totalReserve, size_t reserveFromBack)
|
||||
}
|
||||
|
||||
Encoder::Encoder(const Block& block)
|
||||
: m_buffer(const_pointer_cast<Buffer>(block.getBuffer()))
|
||||
: m_buffer(std::const_pointer_cast<Buffer>(block.getBuffer()))
|
||||
, m_begin(m_buffer->begin() + (block.begin() - m_buffer->begin()))
|
||||
, m_end(m_buffer->begin() + (block.end() - m_buffer->begin()))
|
||||
{
|
||||
@@ -95,68 +94,40 @@ Encoder::reserve(size_t size, bool addInFront)
|
||||
}
|
||||
|
||||
size_t
|
||||
Encoder::prependByte(uint8_t value)
|
||||
Encoder::prependBytes(span<const uint8_t> bytes)
|
||||
{
|
||||
reserveFront(1);
|
||||
|
||||
m_begin--;
|
||||
*m_begin = value;
|
||||
return 1;
|
||||
return prependRange(bytes.begin(), bytes.end());
|
||||
}
|
||||
|
||||
size_t
|
||||
Encoder::appendByte(uint8_t value)
|
||||
Encoder::appendBytes(span<const uint8_t> bytes)
|
||||
{
|
||||
reserveBack(1);
|
||||
|
||||
*m_end = value;
|
||||
m_end++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
Encoder::prependByteArray(const uint8_t* array, size_t length)
|
||||
{
|
||||
reserveFront(length);
|
||||
|
||||
m_begin -= length;
|
||||
std::copy(array, array + length, m_begin);
|
||||
return length;
|
||||
}
|
||||
|
||||
size_t
|
||||
Encoder::appendByteArray(const uint8_t* array, size_t length)
|
||||
{
|
||||
reserveBack(length);
|
||||
|
||||
std::copy(array, array + length, m_end);
|
||||
m_end += length;
|
||||
return length;
|
||||
return appendRange(bytes.begin(), bytes.end());
|
||||
}
|
||||
|
||||
size_t
|
||||
Encoder::prependVarNumber(uint64_t varNumber)
|
||||
{
|
||||
if (varNumber < 253) {
|
||||
prependByte(static_cast<uint8_t>(varNumber));
|
||||
prependBytes({static_cast<uint8_t>(varNumber)});
|
||||
return 1;
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
|
||||
uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
|
||||
prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
|
||||
prependByte(253);
|
||||
prependBytes({reinterpret_cast<const uint8_t*>(&value), 2});
|
||||
prependBytes({253});
|
||||
return 3;
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
|
||||
uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
|
||||
prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
|
||||
prependByte(254);
|
||||
prependBytes({reinterpret_cast<const uint8_t*>(&value), 4});
|
||||
prependBytes({254});
|
||||
return 5;
|
||||
}
|
||||
else {
|
||||
uint64_t value = endian::native_to_big(varNumber);
|
||||
prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
|
||||
prependByte(255);
|
||||
prependBytes({reinterpret_cast<const uint8_t*>(&value), 8});
|
||||
prependBytes({255});
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
@@ -165,25 +136,25 @@ size_t
|
||||
Encoder::appendVarNumber(uint64_t varNumber)
|
||||
{
|
||||
if (varNumber < 253) {
|
||||
appendByte(static_cast<uint8_t>(varNumber));
|
||||
appendBytes({static_cast<uint8_t>(varNumber)});
|
||||
return 1;
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
|
||||
appendByte(253);
|
||||
appendBytes({253});
|
||||
uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
|
||||
appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
|
||||
appendBytes({reinterpret_cast<const uint8_t*>(&value), 2});
|
||||
return 3;
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
|
||||
appendByte(254);
|
||||
appendBytes({254});
|
||||
uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
|
||||
appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
|
||||
appendBytes({reinterpret_cast<const uint8_t*>(&value), 4});
|
||||
return 5;
|
||||
}
|
||||
else {
|
||||
appendByte(255);
|
||||
appendBytes({255});
|
||||
uint64_t value = endian::native_to_big(varNumber);
|
||||
appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
|
||||
appendBytes({reinterpret_cast<const uint8_t*>(&value), 8});
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
@@ -192,19 +163,19 @@ size_t
|
||||
Encoder::prependNonNegativeInteger(uint64_t varNumber)
|
||||
{
|
||||
if (varNumber <= std::numeric_limits<uint8_t>::max()) {
|
||||
return prependByte(static_cast<uint8_t>(varNumber));
|
||||
return prependBytes({static_cast<uint8_t>(varNumber)});
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
|
||||
uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
|
||||
return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
|
||||
return prependBytes({reinterpret_cast<const uint8_t*>(&value), 2});
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
|
||||
uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
|
||||
return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
|
||||
return prependBytes({reinterpret_cast<const uint8_t*>(&value), 4});
|
||||
}
|
||||
else {
|
||||
uint64_t value = endian::native_to_big(varNumber);
|
||||
return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
|
||||
return prependBytes({reinterpret_cast<const uint8_t*>(&value), 8});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,63 +183,20 @@ size_t
|
||||
Encoder::appendNonNegativeInteger(uint64_t varNumber)
|
||||
{
|
||||
if (varNumber <= std::numeric_limits<uint8_t>::max()) {
|
||||
return appendByte(static_cast<uint8_t>(varNumber));
|
||||
return appendBytes({static_cast<uint8_t>(varNumber)});
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
|
||||
uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
|
||||
return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
|
||||
return appendBytes({reinterpret_cast<const uint8_t*>(&value), 2});
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
|
||||
uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
|
||||
return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
|
||||
return appendBytes({reinterpret_cast<const uint8_t*>(&value), 4});
|
||||
}
|
||||
else {
|
||||
uint64_t value = endian::native_to_big(varNumber);
|
||||
return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
|
||||
return appendBytes({reinterpret_cast<const uint8_t*>(&value), 8});
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
Encoder::prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize)
|
||||
{
|
||||
size_t totalLength = prependByteArray(array, arraySize);
|
||||
totalLength += prependVarNumber(arraySize);
|
||||
totalLength += prependVarNumber(type);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
size_t
|
||||
Encoder::appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize)
|
||||
{
|
||||
size_t totalLength = appendVarNumber(type);
|
||||
totalLength += appendVarNumber(arraySize);
|
||||
totalLength += appendByteArray(array, arraySize);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
size_t
|
||||
Encoder::prependBlock(const Block& block)
|
||||
{
|
||||
if (block.hasWire()) {
|
||||
return prependByteArray(block.wire(), block.size());
|
||||
}
|
||||
else {
|
||||
return prependByteArrayBlock(block.type(), block.value(), block.value_size());
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
Encoder::appendBlock(const Block& block)
|
||||
{
|
||||
if (block.hasWire()) {
|
||||
return appendByteArray(block.wire(), block.size());
|
||||
}
|
||||
else {
|
||||
return appendByteArrayBlock(block.type(), block.value(), block.value_size());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace encoding
|
||||
} // namespace ndn
|
||||
} // namespace ndn::encoding
|
||||
+77
-138
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,45 +19,36 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_ENCODING_ENCODER_HPP
|
||||
#define NDN_ENCODING_ENCODER_HPP
|
||||
#ifndef NDN_CXX_ENCODING_ENCODER_HPP
|
||||
#define NDN_CXX_ENCODING_ENCODER_HPP
|
||||
|
||||
#include "ndn-cxx/encoding/block.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace encoding {
|
||||
#include <algorithm>
|
||||
|
||||
namespace ndn::encoding {
|
||||
|
||||
/**
|
||||
* @brief Helper class to perform TLV encoding
|
||||
* Interface of this class (mostly) matches interface of Estimator class
|
||||
* @brief Helper class to perform TLV encoding.
|
||||
*
|
||||
* The interface of this class (mostly) matches that of the Estimator class.
|
||||
*
|
||||
* @sa Estimator
|
||||
*/
|
||||
class Encoder : noncopyable
|
||||
{
|
||||
public: // common interface between Encoder and Estimator
|
||||
/**
|
||||
* @brief Prepend a byte
|
||||
* @brief Prepend a sequence of bytes
|
||||
*/
|
||||
size_t
|
||||
prependByte(uint8_t value);
|
||||
prependBytes(span<const uint8_t> bytes);
|
||||
|
||||
/**
|
||||
* @brief Append a byte
|
||||
* @brief Append a sequence of bytes
|
||||
*/
|
||||
size_t
|
||||
appendByte(uint8_t value);
|
||||
|
||||
/**
|
||||
* @brief Prepend a byte array @p array of length @p length
|
||||
*/
|
||||
size_t
|
||||
prependByteArray(const uint8_t* array, size_t length);
|
||||
|
||||
/**
|
||||
* @brief Append a byte array @p array of length @p length
|
||||
*/
|
||||
size_t
|
||||
appendByteArray(const uint8_t* array, size_t length);
|
||||
appendBytes(span<const uint8_t> bytes);
|
||||
|
||||
/**
|
||||
* @brief Prepend range of bytes from the range [@p first, @p last)
|
||||
@@ -74,57 +65,33 @@ public: // common interface between Encoder and Estimator
|
||||
appendRange(Iterator first, Iterator last);
|
||||
|
||||
/**
|
||||
* @brief Prepend VarNumber @p varNumber of NDN TLV encoding
|
||||
* @sa http://named-data.net/doc/ndn-tlv/
|
||||
* @brief Prepend @p number encoded as a VAR-NUMBER in NDN-TLV format
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
|
||||
*/
|
||||
size_t
|
||||
prependVarNumber(uint64_t varNumber);
|
||||
prependVarNumber(uint64_t number);
|
||||
|
||||
/**
|
||||
* @brief Prepend VarNumber @p varNumber of NDN TLV encoding
|
||||
* @sa http://named-data.net/doc/ndn-tlv/
|
||||
* @brief Append @p number encoded as a VAR-NUMBER in NDN-TLV format
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
|
||||
*/
|
||||
size_t
|
||||
appendVarNumber(uint64_t varNumber);
|
||||
appendVarNumber(uint64_t number);
|
||||
|
||||
/**
|
||||
* @brief Prepend non-negative integer @p integer of NDN TLV encoding
|
||||
* @sa http://named-data.net/doc/ndn-tlv/
|
||||
* @brief Prepend @p integer encoded as a NonNegativeInteger in NDN-TLV format
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
|
||||
*/
|
||||
size_t
|
||||
prependNonNegativeInteger(uint64_t integer);
|
||||
|
||||
/**
|
||||
* @brief Append non-negative integer @p integer of NDN TLV encoding
|
||||
* @sa http://named-data.net/doc/ndn-tlv/
|
||||
* @brief Append @p integer encoded as a NonNegativeInteger in NDN-TLV format
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
|
||||
*/
|
||||
size_t
|
||||
appendNonNegativeInteger(uint64_t integer);
|
||||
|
||||
/**
|
||||
* @brief Prepend TLV block of type @p type and value from buffer @p array of size @p arraySize
|
||||
*/
|
||||
size_t
|
||||
prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize);
|
||||
|
||||
/**
|
||||
* @brief Append TLV block of type @p type and value from buffer @p array of size @p arraySize
|
||||
*/
|
||||
size_t
|
||||
appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize);
|
||||
|
||||
/**
|
||||
* @brief Prepend TLV block @p block
|
||||
*/
|
||||
size_t
|
||||
prependBlock(const Block& block);
|
||||
|
||||
/**
|
||||
* @brief Append TLV block @p block
|
||||
*/
|
||||
size_t
|
||||
appendBlock(const Block& block);
|
||||
|
||||
public: // unique interface to the Encoder
|
||||
using value_type = Buffer::value_type;
|
||||
using iterator = Buffer::iterator;
|
||||
@@ -183,56 +150,83 @@ public: // unique interface to the Encoder
|
||||
* @brief Get size of the underlying buffer
|
||||
*/
|
||||
size_t
|
||||
capacity() const noexcept;
|
||||
capacity() const noexcept
|
||||
{
|
||||
return m_buffer->size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get underlying buffer
|
||||
*/
|
||||
shared_ptr<Buffer>
|
||||
getBuffer() const noexcept;
|
||||
getBuffer() const noexcept
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
public: // accessors
|
||||
/**
|
||||
* @brief Get an iterator pointing to the first byte of the encoded buffer
|
||||
* @brief Returns an iterator pointing to the first byte of the encoded buffer
|
||||
*/
|
||||
iterator
|
||||
begin();
|
||||
begin() noexcept
|
||||
{
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an iterator pointing to the past-the-end byte of the encoded buffer
|
||||
* @brief Returns an iterator pointing to the first byte of the encoded buffer
|
||||
*/
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns an iterator pointing to the past-the-end byte of the encoded buffer
|
||||
*/
|
||||
iterator
|
||||
end();
|
||||
end() noexcept
|
||||
{
|
||||
return m_end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an iterator pointing to the first byte of the encoded buffer
|
||||
* @brief Returns an iterator pointing to the past-the-end byte of the encoded buffer
|
||||
*/
|
||||
const_iterator
|
||||
begin() const;
|
||||
end() const noexcept
|
||||
{
|
||||
return m_end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an iterator pointing to the past-the-end byte of the encoded buffer
|
||||
*/
|
||||
const_iterator
|
||||
end() const;
|
||||
|
||||
/**
|
||||
* @brief Get a pointer to the first byte of the encoded buffer
|
||||
* @brief Returns a pointer to the first byte of the encoded buffer
|
||||
*/
|
||||
uint8_t*
|
||||
buf();
|
||||
data() noexcept
|
||||
{
|
||||
return &*m_begin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a pointer to the first byte of the encoded buffer
|
||||
* @brief Returns a pointer to the first byte of the encoded buffer
|
||||
*/
|
||||
const uint8_t*
|
||||
buf() const;
|
||||
data() const noexcept
|
||||
{
|
||||
return &*m_begin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the size of the encoded buffer
|
||||
* @brief Returns the size of the encoded buffer
|
||||
*/
|
||||
size_t
|
||||
size() const noexcept;
|
||||
size() const noexcept
|
||||
{
|
||||
return static_cast<size_t>(std::distance(m_begin, m_end));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create Block from the underlying buffer
|
||||
@@ -253,71 +247,17 @@ private:
|
||||
iterator m_end;
|
||||
};
|
||||
|
||||
inline size_t
|
||||
Encoder::size() const noexcept
|
||||
{
|
||||
return m_end - m_begin;
|
||||
}
|
||||
|
||||
inline shared_ptr<Buffer>
|
||||
Encoder::getBuffer() const noexcept
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
inline size_t
|
||||
Encoder::capacity() const noexcept
|
||||
{
|
||||
return m_buffer->size();
|
||||
}
|
||||
|
||||
inline Buffer::iterator
|
||||
Encoder::begin()
|
||||
{
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
inline Buffer::iterator
|
||||
Encoder::end()
|
||||
{
|
||||
return m_end;
|
||||
}
|
||||
|
||||
inline Buffer::const_iterator
|
||||
Encoder::begin() const
|
||||
{
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
inline Buffer::const_iterator
|
||||
Encoder::end() const
|
||||
{
|
||||
return m_end;
|
||||
}
|
||||
|
||||
inline uint8_t*
|
||||
Encoder::buf()
|
||||
{
|
||||
return &(*m_begin);
|
||||
}
|
||||
|
||||
inline const uint8_t*
|
||||
Encoder::buf() const
|
||||
{
|
||||
return &(*m_begin);
|
||||
}
|
||||
|
||||
template<class Iterator>
|
||||
size_t
|
||||
Encoder::prependRange(Iterator first, Iterator last)
|
||||
{
|
||||
using ValueType = typename std::iterator_traits<Iterator>::value_type;
|
||||
static_assert(sizeof(ValueType) == 1 && !std::is_same<ValueType, bool>::value, "");
|
||||
static_assert(sizeof(ValueType) == 1 && !std::is_same_v<ValueType, bool>);
|
||||
|
||||
size_t length = std::distance(first, last);
|
||||
reserveFront(length);
|
||||
|
||||
m_begin -= length;
|
||||
std::advance(m_begin, -length);
|
||||
std::copy(first, last, m_begin);
|
||||
return length;
|
||||
}
|
||||
@@ -327,17 +267,16 @@ size_t
|
||||
Encoder::appendRange(Iterator first, Iterator last)
|
||||
{
|
||||
using ValueType = typename std::iterator_traits<Iterator>::value_type;
|
||||
static_assert(sizeof(ValueType) == 1 && !std::is_same<ValueType, bool>::value, "");
|
||||
static_assert(sizeof(ValueType) == 1 && !std::is_same_v<ValueType, bool>);
|
||||
|
||||
size_t length = std::distance(first, last);
|
||||
reserveBack(length);
|
||||
|
||||
std::copy(first, last, m_end);
|
||||
m_end += length;
|
||||
std::advance(m_end, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
} // namespace encoding
|
||||
} // namespace ndn
|
||||
} // namespace ndn::encoding
|
||||
|
||||
#endif // NDN_ENCODING_ENCODER_HPP
|
||||
#endif // NDN_CXX_ENCODING_ENCODER_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2021 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,8 +19,8 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_ENCODING_ENCODING_BUFFER_FWD_HPP
|
||||
#define NDN_ENCODING_ENCODING_BUFFER_FWD_HPP
|
||||
#ifndef NDN_CXX_ENCODING_ENCODING_BUFFER_FWD_HPP
|
||||
#define NDN_CXX_ENCODING_ENCODING_BUFFER_FWD_HPP
|
||||
|
||||
#include "ndn-cxx/detail/common.hpp"
|
||||
|
||||
@@ -58,4 +58,4 @@ using encoding::EncodingEstimator;
|
||||
template size_t \
|
||||
ClassName::wireEncode<::ndn::encoding::EstimatorTag>(::ndn::EncodingEstimator&) const \
|
||||
|
||||
#endif // NDN_ENCODING_ENCODING_BUFFER_FWD_HPP
|
||||
#endif // NDN_CXX_ENCODING_ENCODING_BUFFER_FWD_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,15 +19,14 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_ENCODING_ENCODING_BUFFER_HPP
|
||||
#define NDN_ENCODING_ENCODING_BUFFER_HPP
|
||||
#ifndef NDN_CXX_ENCODING_ENCODING_BUFFER_HPP
|
||||
#define NDN_CXX_ENCODING_ENCODING_BUFFER_HPP
|
||||
|
||||
#include "ndn-cxx/encoding/encoding-buffer-fwd.hpp"
|
||||
#include "ndn-cxx/encoding/encoder.hpp"
|
||||
#include "ndn-cxx/encoding/estimator.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace encoding {
|
||||
namespace ndn::encoding {
|
||||
|
||||
/**
|
||||
* @brief EncodingImpl specialization for actual TLV encoding
|
||||
@@ -62,7 +61,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace encoding
|
||||
} // namespace ndn
|
||||
} // namespace ndn::encoding
|
||||
|
||||
#endif // NDN_ENCODING_ENCODING_BUFFER_HPP
|
||||
#endif // NDN_CXX_ENCODING_ENCODING_BUFFER_HPP
|
||||
@@ -1,107 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received copies of the GNU General Public License and GNU Lesser
|
||||
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#include "ndn-cxx/encoding/estimator.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace encoding {
|
||||
|
||||
size_t
|
||||
Estimator::prependVarNumber(uint64_t varNumber) const noexcept
|
||||
{
|
||||
if (varNumber < 253) {
|
||||
return 1;
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
|
||||
return 3;
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
|
||||
return 5;
|
||||
}
|
||||
else {
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
Estimator::appendVarNumber(uint64_t varNumber) const noexcept
|
||||
{
|
||||
return prependVarNumber(varNumber);
|
||||
}
|
||||
|
||||
size_t
|
||||
Estimator::prependNonNegativeInteger(uint64_t varNumber) const noexcept
|
||||
{
|
||||
if (varNumber <= std::numeric_limits<uint8_t>::max()) {
|
||||
return 1;
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
|
||||
return 2;
|
||||
}
|
||||
else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
|
||||
return 4;
|
||||
}
|
||||
else {
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
Estimator::appendNonNegativeInteger(uint64_t varNumber) const noexcept
|
||||
{
|
||||
return prependNonNegativeInteger(varNumber);
|
||||
}
|
||||
|
||||
size_t
|
||||
Estimator::prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept
|
||||
{
|
||||
size_t totalLength = arraySize;
|
||||
totalLength += prependVarNumber(arraySize);
|
||||
totalLength += prependVarNumber(type);
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
size_t
|
||||
Estimator::appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept
|
||||
{
|
||||
return prependByteArrayBlock(type, array, arraySize);
|
||||
}
|
||||
|
||||
size_t
|
||||
Estimator::prependBlock(const Block& block) const
|
||||
{
|
||||
if (block.hasWire()) {
|
||||
return block.size();
|
||||
}
|
||||
else {
|
||||
return prependByteArrayBlock(block.type(), block.value(), block.value_size());
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
Estimator::appendBlock(const Block& block) const
|
||||
{
|
||||
return prependBlock(block);
|
||||
}
|
||||
|
||||
} // namespace encoding
|
||||
} // namespace ndn
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -19,132 +19,98 @@
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#ifndef NDN_ENCODING_ESTIMATOR_HPP
|
||||
#define NDN_ENCODING_ESTIMATOR_HPP
|
||||
#ifndef NDN_CXX_ENCODING_ESTIMATOR_HPP
|
||||
#define NDN_CXX_ENCODING_ESTIMATOR_HPP
|
||||
|
||||
#include "ndn-cxx/encoding/block.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace encoding {
|
||||
namespace ndn::encoding {
|
||||
|
||||
/**
|
||||
* @brief Helper class to estimate size of TLV encoding
|
||||
* Interface of this class (mostly) matches interface of Encoder class
|
||||
* @brief Helper class to estimate size of TLV encoding.
|
||||
*
|
||||
* The interface of this class (mostly) matches that of the Encoder class.
|
||||
*
|
||||
* @sa Encoder
|
||||
*/
|
||||
class Estimator : noncopyable
|
||||
{
|
||||
public: // common interface between Encoder and Estimator
|
||||
/**
|
||||
* @brief Prepend a byte
|
||||
* @brief Prepend a sequence of bytes
|
||||
*/
|
||||
constexpr size_t
|
||||
prependByte(uint8_t) const noexcept
|
||||
prependBytes(span<const uint8_t> bytes) const noexcept
|
||||
{
|
||||
return 1;
|
||||
return bytes.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append a byte
|
||||
* @brief Append a sequence of bytes
|
||||
*/
|
||||
constexpr size_t
|
||||
appendByte(uint8_t) const noexcept
|
||||
appendBytes(span<const uint8_t> bytes) const noexcept
|
||||
{
|
||||
return 1;
|
||||
return bytes.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend a byte array @p array of length @p length
|
||||
*/
|
||||
constexpr size_t
|
||||
prependByteArray(const uint8_t*, size_t length) const noexcept
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append a byte array @p array of length @p length
|
||||
*/
|
||||
constexpr size_t
|
||||
appendByteArray(const uint8_t*, size_t length) const noexcept
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend range of bytes from the range [@p first, @p last)
|
||||
* @brief Prepend bytes from the range [@p first, @p last)
|
||||
*/
|
||||
template<class Iterator>
|
||||
size_t
|
||||
constexpr size_t
|
||||
prependRange(Iterator first, Iterator last) const noexcept
|
||||
{
|
||||
return std::distance(first, last);
|
||||
return static_cast<size_t>(std::distance(first, last));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append range of bytes from the range [@p first, @p last)
|
||||
* @brief Append bytes from the range [@p first, @p last)
|
||||
*/
|
||||
template<class Iterator>
|
||||
size_t
|
||||
constexpr size_t
|
||||
appendRange(Iterator first, Iterator last) const noexcept
|
||||
{
|
||||
return std::distance(first, last);
|
||||
return static_cast<size_t>(std::distance(first, last));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend VarNumber @p varNumber of NDN TLV encoding
|
||||
* @sa http://named-data.net/doc/ndn-tlv/
|
||||
* @brief Prepend @p n in VarNumber encoding
|
||||
*/
|
||||
size_t
|
||||
prependVarNumber(uint64_t varNumber) const noexcept;
|
||||
constexpr size_t
|
||||
prependVarNumber(uint64_t n) const noexcept
|
||||
{
|
||||
return tlv::sizeOfVarNumber(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend VarNumber @p varNumber of NDN TLV encoding
|
||||
* @sa http://named-data.net/doc/ndn-tlv/
|
||||
* @brief Append @p n in VarNumber encoding
|
||||
*/
|
||||
size_t
|
||||
appendVarNumber(uint64_t varNumber) const noexcept;
|
||||
constexpr size_t
|
||||
appendVarNumber(uint64_t n) const noexcept
|
||||
{
|
||||
return tlv::sizeOfVarNumber(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend non-negative integer @p integer of NDN TLV encoding
|
||||
* @sa http://named-data.net/doc/ndn-tlv/
|
||||
* @brief Prepend @p n in NonNegativeInteger encoding
|
||||
*/
|
||||
size_t
|
||||
prependNonNegativeInteger(uint64_t integer) const noexcept;
|
||||
constexpr size_t
|
||||
prependNonNegativeInteger(uint64_t n) const noexcept
|
||||
{
|
||||
return tlv::sizeOfNonNegativeInteger(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append non-negative integer @p integer of NDN TLV encoding
|
||||
* @sa http://named-data.net/doc/ndn-tlv/
|
||||
* @brief Append @p n in NonNegativeInteger encoding
|
||||
*/
|
||||
size_t
|
||||
appendNonNegativeInteger(uint64_t integer) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Prepend TLV block of type @p type and value from buffer @p array of size @p arraySize
|
||||
*/
|
||||
size_t
|
||||
prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Append TLV block of type @p type and value from buffer @p array of size @p arraySize
|
||||
*/
|
||||
size_t
|
||||
appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Prepend TLV block @p block
|
||||
*/
|
||||
size_t
|
||||
prependBlock(const Block& block) const;
|
||||
|
||||
/**
|
||||
* @brief Append TLV block @p block
|
||||
*/
|
||||
size_t
|
||||
appendBlock(const Block& block) const;
|
||||
constexpr size_t
|
||||
appendNonNegativeInteger(uint64_t n) const noexcept
|
||||
{
|
||||
return tlv::sizeOfNonNegativeInteger(n);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace encoding
|
||||
} // namespace ndn
|
||||
} // namespace ndn::encoding
|
||||
|
||||
#endif // NDN_ENCODING_ESTIMATOR_HPP
|
||||
#endif // NDN_CXX_ENCODING_ESTIMATOR_HPP
|
||||
Loaded 100 of 719 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user