Compare commits
107
Commits
ndn-cxx-0.8.0
...
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 |
No files matched your search
@@ -3,66 +3,15 @@ on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.conf.sample*'
|
||||
- '*.md'
|
||||
- '.mailmap'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
name: ${{ matrix.compiler }} on ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
compiler: [g++-8, g++-9, g++-10, g++-11,
|
||||
clang++-7, clang++-8, clang++-9, clang++-10, clang++-11, clang++-12]
|
||||
os: [ubuntu-20.04]
|
||||
include:
|
||||
- compiler: g++-7
|
||||
os: ubuntu-18.04
|
||||
- compiler: clang++-5.0
|
||||
os: ubuntu-18.04
|
||||
- compiler: clang++-6.0
|
||||
os: ubuntu-18.04
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CXX: ${{ matrix.compiler }}
|
||||
NODE_LABELS: Linux Ubuntu
|
||||
WAF_JOBS: 2
|
||||
steps:
|
||||
- name: Install C++ compiler
|
||||
run: |
|
||||
sudo apt-get -qy install ${CXX/clang++/clang}
|
||||
${CXX} --version
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Build and test
|
||||
run: ./.jenkins
|
||||
|
||||
macos:
|
||||
name: Xcode ${{ matrix.xcode }} on ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
xcode: ['11.3', '11.7', '12.4']
|
||||
os: [macos-10.15]
|
||||
include:
|
||||
- xcode: '12.5'
|
||||
os: macos-11
|
||||
- xcode: '13.2'
|
||||
os: macos-11
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
NODE_LABELS: OSX
|
||||
WAF_JOBS: 3
|
||||
steps:
|
||||
- name: Set up Xcode
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: ${{ matrix.xcode }}
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Build and test
|
||||
run: ./.jenkins
|
||||
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 }}
|
||||
+14
-31
@@ -1,38 +1,21 @@
|
||||
name: Docs
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
- '.mailmap'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
skip-deploy:
|
||||
description: 'Skip deployment?'
|
||||
required: true
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-11, ubuntu-20.04]
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
JOB_NAME: Docs
|
||||
WAF_JOBS: 3
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
case ${RUNNER_OS} in
|
||||
Linux) export NODE_LABELS="Linux Ubuntu" ;;
|
||||
macOS) export NODE_LABELS="OSX" ;;
|
||||
esac
|
||||
find .jenkins.d/ -type f -name '[1-9]*.sh' -exec chmod -x '{}' +
|
||||
./.jenkins
|
||||
- name: Build documentation
|
||||
run: |
|
||||
./waf --color=yes configure
|
||||
./waf --color=yes build --targets=version.hpp
|
||||
./waf --color=yes build --targets=manpages
|
||||
./waf --color=yes docs
|
||||
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
|
||||
@@ -1,13 +1,39 @@
|
||||
#!/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
|
||||
|
||||
if has Linux $NODE_LABELS; then
|
||||
export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
|
||||
fi
|
||||
export CACHE_DIR=${CACHE_DIR:-/tmp}
|
||||
export WAF_JOBS=${WAF_JOBS:-1}
|
||||
[[ $JOB_NAME == *"code-coverage" ]] && export DISABLE_ASAN=yes
|
||||
|
||||
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
|
||||
|
||||
+29
-40
@@ -1,49 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
set -eo pipefail
|
||||
|
||||
if has OSX $NODE_LABELS; then
|
||||
FORMULAE=(boost openssl pkg-config)
|
||||
if [[ $JOB_NAME == *"Docs" ]]; then
|
||||
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)
|
||||
fi
|
||||
PIP_PKGS+=(sphinx sphinxcontrib-doxylink)
|
||||
;;
|
||||
esac
|
||||
|
||||
set -x
|
||||
|
||||
if [[ $ID == macos ]]; then
|
||||
if [[ -n $GITHUB_ACTIONS ]]; then
|
||||
# GitHub Actions runners have a large number of pre-installed
|
||||
# Homebrew 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
|
||||
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
|
||||
fi
|
||||
|
||||
if [[ $JOB_NAME == *"Docs" ]]; then
|
||||
pip3 install --upgrade --upgrade-strategy=eager sphinx sphinxcontrib-doxylink
|
||||
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 build-essential pkg-config python3-minimal \
|
||||
libboost-all-dev libssl-dev libsqlite3-dev
|
||||
|
||||
case $JOB_NAME in
|
||||
*code-coverage)
|
||||
sudo apt-get -qy install lcov python3-pip
|
||||
pip3 install --user --upgrade --upgrade-strategy=eager 'gcovr~=5.0'
|
||||
;;
|
||||
*Docs)
|
||||
sudo apt-get -qy install doxygen graphviz python3-pip
|
||||
pip3 install --user --upgrade --upgrade-strategy=eager sphinx sphinxcontrib-doxylink
|
||||
;;
|
||||
esac
|
||||
|
||||
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 key-gen "/tmp/jenkins/$NODE_NAME" | ndnsec cert-install -
|
||||
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
|
||||
@@ -1,18 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
set -exo pipefail
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
# 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 -j$WAF_JOBS \
|
||||
--object-directory build \
|
||||
gcovr --object-directory build \
|
||||
--filter ndn-cxx/ \
|
||||
--exclude ndn-cxx/detail/nonstd/ \
|
||||
--exclude-throw-branches \
|
||||
--exclude-unreachable-branches \
|
||||
--print-summary \
|
||||
--cobertura build/coverage.xml \
|
||||
--html-details build/gcovr/ \
|
||||
--xml build/coverage.xml
|
||||
--print-summary
|
||||
|
||||
# Generate a detailed HTML report using lcov
|
||||
lcov --quiet \
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#!/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
|
||||
@@ -13,12 +11,12 @@ if [[ -n $DISABLE_HEADERS_CHECK ]]; then
|
||||
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
|
||||
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
|
||||
|
||||
@@ -28,9 +26,8 @@ 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
|
||||
|
||||
+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
|
||||
+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()
|
||||
@@ -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
|
||||
@@ -19,8 +19,11 @@ 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',
|
||||
@@ -43,7 +46,7 @@ def __openssl_find_root_and_version_file(self, root):
|
||||
|
||||
openssl_dirs = OPENSSL_DIR
|
||||
if Utils.unversioned_sys_platform() == 'darwin':
|
||||
openssl_dirs = OPENSSL_DIR_OSX
|
||||
openssl_dirs = OPENSSL_DIR_MACOS
|
||||
|
||||
for dir in openssl_dirs:
|
||||
file = self.__openssl_get_version_file(dir)
|
||||
|
||||
+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>
|
||||
|
||||
+9
-20
@@ -6,11 +6,8 @@ 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)
|
||||
@@ -18,29 +15,21 @@ ndn-cxx relies on third-party software, licensed under the following licenses:
|
||||
- span-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/span-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)
|
||||
|
||||
- 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,43 +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
|
||||
|
||||
</div>
|
||||
|
||||
[](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++14 library implementing Named Data Networking (NDN) primitives
|
||||
**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
|
||||
+38
-41
@@ -7,23 +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)
|
||||
- Ubuntu 21.10 (amd64)
|
||||
- macOS 10.15
|
||||
- macOS 11 (Intel only)
|
||||
- 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:
|
||||
|
||||
- Alpine >= 3.12
|
||||
- Debian >= 10
|
||||
- Fedora >= 29
|
||||
- Gentoo Linux
|
||||
- Raspberry Pi OS (formerly Raspbian) >= 2019-06-20
|
||||
- FreeBSD >= 11.3
|
||||
- macOS 10.14
|
||||
- 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
|
||||
-------------
|
||||
@@ -31,18 +30,18 @@ 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::
|
||||
|
||||
@@ -64,7 +63,6 @@ development tools and libraries:
|
||||
.. code-block:: sh
|
||||
|
||||
brew install boost openssl pkg-config
|
||||
brew install python # only on macOS 10.14 and earlier
|
||||
|
||||
.. warning::
|
||||
|
||||
@@ -83,10 +81,10 @@ Optional
|
||||
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.
|
||||
|
||||
@@ -98,7 +96,7 @@ The following lists the steps to install these prerequisites on various common p
|
||||
|
||||
export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
|
||||
|
||||
- On **Ubuntu**:
|
||||
- On **Debian** and **Ubuntu**:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
@@ -109,7 +107,6 @@ The following lists the steps to install these prerequisites on various common p
|
||||
|
||||
.. 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
|
||||
|
||||
@@ -124,7 +121,7 @@ The following lists the steps to install these prerequisites on various common p
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
sudo pkg install doxygen graphviz py37-sphinx
|
||||
sudo pkg install doxygen graphviz py39-sphinx
|
||||
|
||||
Build
|
||||
-----
|
||||
@@ -137,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
|
||||
|
||||
@@ -164,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
|
||||
|
||||
@@ -193,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
|
||||
@@ -215,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
|
||||
@@ -306,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
|
||||
@@ -317,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
|
||||
+14
-16
@@ -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 is available at `<https://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-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
|
||||
--------------
|
||||
@@ -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:
|
||||
|
||||
@@ -479,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.
|
||||
|
||||
|
||||
+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-2021 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'),
|
||||
}
|
||||
+4
-42
@@ -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
|
||||
@@ -774,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
|
||||
@@ -830,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
|
||||
@@ -1178,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
|
||||
@@ -1739,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.
|
||||
@@ -1821,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
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -1920,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
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -2119,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.
|
||||
|
||||
+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: 43-49,52-55,63,77,83
|
||||
: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: 39-42,55,62-64,79,87,91
|
||||
: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: 37-38,54-57,60,91,104-107,112-114
|
||||
:emphasize-lines: 47-50,53,84,96-99,104-106
|
||||
+37
-33
@@ -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/certificate`
|
||||
+ :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>`__.
|
||||
+5
-5
@@ -2,9 +2,9 @@ Man pages
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
:maxdepth: 1
|
||||
|
||||
ndn-client.conf <manpages/ndn-client.conf>
|
||||
ndn-log: ndn-cxx logging <manpages/ndn-log>
|
||||
manpages/ndnsec*
|
||||
ndn-client.conf <manpages/ndn-client.conf>
|
||||
ndn-log: ndn-cxx logging <manpages/ndn-log>
|
||||
manpages/ndnsec*
|
||||
@@ -75,7 +75,7 @@ tpm
|
||||
|
||||
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.
|
||||
|
||||
The ``[location]`` parameter is ignored.
|
||||
|
||||
@@ -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
|
||||
@@ -75,17 +75,18 @@ Example
|
||||
ug/vLAIgY3xJITCwf55sqey33q5GIQSk1TRCkNNl58ojvPs5sNU=
|
||||
|
||||
$ ndnsec-cert-dump -p -f signed.cert
|
||||
Certificate name:
|
||||
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
|
||||
@@ -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.8.0.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
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ New features
|
||||
+ New :ndn-cxx:`SignatureSha256WithEcdsa` signature type
|
||||
|
||||
+ Updates in ``Signature`` data structure to reflect changes in the `NDN-TLV spec v0.1.1
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.1.1/>`_
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.1.1/>`__
|
||||
|
||||
- **Wire encoding**
|
||||
|
||||
@@ -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**
|
||||
@@ -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,7 +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 the NDN Certificate format </specs/certificate>`.
|
||||
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,10 +13,11 @@ 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
|
||||
|
||||
* :doc:`/specs/certificate` (: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`)
|
||||
@@ -62,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`)
|
||||
|
||||
|
||||
@@ -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 :doc:`/specs/certificate`.
|
||||
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
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ Important changes
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Flip default value of ``CanBePrefix`` to **false** (:issue:`4582`). This means that
|
||||
Interests created without explicitly specifying ``CanBePrefix`` option, will be treaded
|
||||
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`)
|
||||
- Change default name component encoding convention to ``TYPED`` (:issue:`5044`)
|
||||
|
||||
- Update TLV-TYPE numbers to revision 3 of the `naming conventions`_
|
||||
|
||||
@@ -19,7 +19,7 @@ Important changes
|
||||
|
||||
- Change TLV-TYPE number of ``IncomingFaceId`` field in NDNLP (:issue:`5185`)
|
||||
|
||||
- Update ``Interest::ForwardingHint`` format (:issue:`5187`)
|
||||
- Update Interest ``ForwardingHint`` format (:issue:`5187`)
|
||||
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -27,19 +27,19 @@ Improvements and bug fixes
|
||||
- Support certificate name, versionless certificate name, and key name options for
|
||||
KeyLocator name in ``ValidatorConfig`` (:issue:`5142`)
|
||||
|
||||
- Fix ``ValidatorConfig`` rule processing bug (:issue:`5145`)
|
||||
|
||||
- Generalize signature verification to allow ``digest-sha256``, effectively adding
|
||||
support of digest integrity verification in ``ValidatorConfig``
|
||||
|
||||
- Enforce ``sig-type`` check in ``ValidatorConfig`` (:issue:`4524`)
|
||||
|
||||
- Refactor and cleanup of ``StatusDatasetContext``, including increase of max payload size
|
||||
of each segment produced by ``StatusDatasetContext`` to 8,000 bytes
|
||||
- Fix ``ValidatorConfig`` rule processing bug (:issue:`5145`)
|
||||
|
||||
- Prevent potential dereferencing of past-the-end iterator in ``Block::value()``
|
||||
|
||||
- Fail early in ``Block::blockFromValue()``, if TLV length is zero
|
||||
- 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
|
||||
|
||||
@@ -50,7 +50,7 @@ Improvements and bug fixes
|
||||
- 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
|
||||
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
|
||||
|
||||
@@ -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
|
||||
+31
-25
@@ -2,39 +2,45 @@ All ndn-cxx Releases
|
||||
====================
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:reversed:
|
||||
:glob:
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:reversed:
|
||||
|
||||
release-notes/*
|
||||
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://named-data.net/doc/ndn-cxx/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/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/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/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/ndn-cxx-0.6.5.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.6.5.tar.bz2.sha256>`__)
|
||||
@@ -42,85 +48,85 @@ All ndn-cxx Releases
|
||||
* **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/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/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/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/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/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/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/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/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/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/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/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/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/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/ndn-cxx-0.2.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.2.0.tar.bz2.sha256>`__)
|
||||
@@ -132,7 +138,7 @@ 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/ndn-cxx-0.1.0.tar.bz2>`__ (`checksum <https://named-data.net/downloads/ndn-cxx-0.1.0.tar.bz2.sha256>`__)
|
||||
|
||||
@@ -4,7 +4,5 @@ Specifications
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
specs/certificate
|
||||
specs/safe-bag
|
||||
specs/validation-error-code
|
||||
specs/signed-interest
|
||||
@@ -1,201 +0,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 alone is not sufficient to serve as the
|
||||
specification of a common NDN certificate format, because additional provisions
|
||||
are required for the latter. For example, a certificate follows a specific
|
||||
naming scheme and may need to include validity period, revocation information,
|
||||
etc. This specification defines the naming and structure of NDN certificates
|
||||
and is complementary to the `NDN packet specification
|
||||
<https://named-data.net/doc/NDN-packet-spec/current/>`__.
|
||||
|
||||
::
|
||||
|
||||
Structure of an NDN certificate
|
||||
+--------------------------+
|
||||
| Name |
|
||||
+--------------------------+
|
||||
| MetaInfo |
|
||||
|+------------------------+|
|
||||
|| ContentType: KEY(2) ||
|
||||
|+------------------------+|
|
||||
|+------------------------+|
|
||||
|| FreshnessPeriod: ~1h ||
|
||||
|+------------------------+|
|
||||
+--------------------------+
|
||||
| Content |
|
||||
|+------------------------+|
|
||||
|| Public Key ||
|
||||
|+------------------------+|
|
||||
+--------------------------+
|
||||
| SignatureInfo |
|
||||
|+------------------------+|
|
||||
|| SignatureType: ... ||
|
||||
|| KeyLocator: ... ||
|
||||
|| ValidityPeriod: ... ||
|
||||
|| ... ||
|
||||
|+------------------------+|
|
||||
+--------------------------+
|
||||
| SignatureValue |
|
||||
+--------------------------+
|
||||
|
||||
.. code-block:: abnf
|
||||
|
||||
Certificate = DATA-TYPE TLV-LENGTH
|
||||
Name ; /<IdentityName>/KEY/<KeyId>/<IssuerId>/<Version>
|
||||
MetaInfo ; ContentType == KEY, FreshnessPeriod required
|
||||
CertificateContent
|
||||
CertificateSignatureInfo
|
||||
SignatureValue
|
||||
|
||||
CertificateContent = CONTENT-TYPE TLV-LENGTH SubjectPublicKeyInfo
|
||||
|
||||
CertificateSignatureInfo = SIGNATURE-INFO-TYPE TLV-LENGTH
|
||||
SignatureType
|
||||
KeyLocator
|
||||
ValidityPeriod
|
||||
*CertificateExtension
|
||||
|
||||
|
||||
Name
|
||||
----
|
||||
|
||||
The name of a certificate consists of five parts as shown below::
|
||||
|
||||
/<IdentityName>/KEY/<KeyId>/<IssuerId>/<Version>
|
||||
|
||||
A certificate name starts with the name of the identity to which the public key is
|
||||
bound. The identity is followed by a literal ``KEY`` GenericNameComponent and by
|
||||
the *KeyId*, *IssuerId*, and *Version* components.
|
||||
|
||||
*KeyId* is an opaque name component that identifies an instance of the public key in
|
||||
the certificate namespace. The value of *KeyId* is controlled by the namespace owner
|
||||
and can be an 8-byte random number, the SHA-256 digest of the certificate's public
|
||||
key, a timestamp, or any other unique numerical identifier.
|
||||
|
||||
*IssuerId* is an opaque name component that identifies the issuer of the certificate.
|
||||
The value is controlled by the certificate issuer and, similar to *KeyId*, can be an
|
||||
8-byte random number, the SHA-256 digest of the issuer's public key, or any other
|
||||
free-form identifier.
|
||||
|
||||
*Version* represents the version number of the certificate. This component is encoded
|
||||
as a VersionNameComponent, following either revision 1 (marker-based) or revision 3
|
||||
(type-based) of the `NDN naming conventions
|
||||
<https://named-data.net/publications/techreports/ndn-tr-22-3-ndn-memo-naming-conventions/>`__.
|
||||
|
||||
For example::
|
||||
|
||||
/edu/ucla/cs/yingdi/KEY/%03%CD...%F1/%9F%D3...%B7/v=1617592200702
|
||||
\_________________/ \___________/\___________/\______________/
|
||||
Identity Name KeyId IssuerId Version
|
||||
|
||||
MetaInfo
|
||||
--------
|
||||
|
||||
The ``ContentType`` must be set to ``KEY`` (2).
|
||||
|
||||
The ``FreshnessPeriod`` must be explicitly specified. The recommended value is 3,600,000 (1 hour).
|
||||
|
||||
Content
|
||||
-------
|
||||
|
||||
The ``Content`` element of a certificate contains the actual bits of the public key, formatted as
|
||||
a DER-encoded `SubjectPublicKeyInfo <https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.7>`__
|
||||
structure.
|
||||
|
||||
SignatureInfo
|
||||
-------------
|
||||
|
||||
The ``SignatureInfo`` element of a certificate is required to include a ``ValidityPeriod``
|
||||
element.
|
||||
|
||||
``ValidityPeriod`` contains two TLV sub-elements: ``NotBefore`` and ``NotAfter``, each
|
||||
carrying a UTC timestamp in *ISO 8601-1:2019* compact format without the final "Z" character
|
||||
("YYYYMMDDThhmmss", e.g., "20201231T235959"). ``NotBefore`` indicates when the certificate
|
||||
takes effect while ``NotAfter`` indicates when the certificate expires.
|
||||
|
||||
.. code-block:: abnf
|
||||
|
||||
ValidityPeriod = VALIDITY-PERIOD-TYPE TLV-LENGTH
|
||||
NotBefore
|
||||
NotAfter
|
||||
|
||||
NotBefore = NOT-BEFORE-TYPE TLV-LENGTH IsoDate "T" IsoTime
|
||||
|
||||
NotAfter = NOT-AFTER-TYPE TLV-LENGTH IsoDate "T" IsoTime
|
||||
|
||||
IsoDate = 8DIGIT ; YYYYMMDD (UTC)
|
||||
|
||||
IsoTime = 6DIGIT ; hhmmss (UTC)
|
||||
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
| Type | Assigned number | Assigned number |
|
||||
| | (decimal) | (hexadecimal) |
|
||||
+=============================================+==================+=================+
|
||||
| ValidityPeriod | 253 | 0xFD |
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
| NotBefore | 254 | 0xFE |
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
| NotAfter | 255 | 0xFF |
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
|
||||
Extensions
|
||||
----------
|
||||
|
||||
A certificate may carry zero or more extension fields in its ``SignatureInfo`` element.
|
||||
An extension can be either critical or non-critical depending on its TLV-TYPE number.
|
||||
A critical TLV-TYPE means that if a validator cannot recognize or parse the extension,
|
||||
the validator must reject the whole certificate. Conversely, an extension with a
|
||||
non-critical TLV-TYPE may be ignored by the validator if it is not recognized. Refer to
|
||||
the general `evolvability rules
|
||||
<https://named-data.net/doc/NDN-packet-spec/current/tlv.html#considerations-for-evolvability-of-tlv-based-encoding>`__
|
||||
of the NDN packet format to determine whether a TLV-TYPE is critical or not.
|
||||
|
||||
The TLV-TYPE number range [256, 511] is reserved for extensions. The currently defined
|
||||
extensions are listed in the table below.
|
||||
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
| Type | Assigned number | Assigned number |
|
||||
| | (decimal) | (hexadecimal) |
|
||||
+=============================================+==================+=================+
|
||||
| AdditionalDescription (non-critical) | 258 | 0x102 |
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
|
||||
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 pairs to provide further details about the certificate.
|
||||
|
||||
.. code-block:: abnf
|
||||
|
||||
CertificateExtension = 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
|
||||
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
| Type | Assigned number | Assigned number |
|
||||
| | (decimal) | (hexadecimal) |
|
||||
+=============================================+==================+=================+
|
||||
| DescriptionEntry | 512 | 0x200 |
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
| DescriptionKey | 513 | 0x201 |
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
| DescriptionValue | 514 | 0x202 |
|
||||
+---------------------------------------------+------------------+-----------------+
|
||||
@@ -1,15 +1,14 @@
|
||||
SafeBag Format for Exported Credentials
|
||||
=======================================
|
||||
|
||||
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. We define **SafeBag**, which contains
|
||||
an :doc:`NDN certificate </specs/certificate>` and the corresponding private key in encrypted
|
||||
form. The private key is formatted as a DER-encoded
|
||||
`EncryptedPrivateKeyInfo <https://datatracker.ietf.org/doc/html/rfc5208#section-6>`__
|
||||
structure as described in PKCS #8.
|
||||
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 TLV-based format of ``SafeBag`` is defined as follows:
|
||||
The TLV encoding of ``SafeBag`` is defined as follows:
|
||||
|
||||
.. code-block:: abnf
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ 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.
|
||||
|
||||
@@ -52,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.
|
||||
|
||||
::
|
||||
|
||||
@@ -84,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.
|
||||
|
||||
::
|
||||
|
||||
@@ -109,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:`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.
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -22,7 +22,7 @@
|
||||
#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`)
|
||||
@@ -33,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()
|
||||
{
|
||||
@@ -46,7 +40,6 @@ public:
|
||||
interestName.appendVersion();
|
||||
|
||||
Interest interest(interestName);
|
||||
interest.setCanBePrefix(false);
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setInterestLifetime(2_s);
|
||||
|
||||
@@ -59,8 +52,8 @@ public:
|
||||
// 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.
|
||||
@@ -96,7 +89,6 @@ private:
|
||||
interestName.appendVersion();
|
||||
|
||||
Interest interest(interestName);
|
||||
interest.setCanBePrefix(false);
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setInterestLifetime(2_s);
|
||||
|
||||
@@ -108,10 +100,10 @@ private:
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -44,7 +44,6 @@ public:
|
||||
interestName.appendVersion();
|
||||
|
||||
Interest interest(interestName);
|
||||
interest.setCanBePrefix(false);
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setInterestLifetime(6_s); // The default is 4 seconds
|
||||
|
||||
|
||||
+12
-13
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -37,33 +37,32 @@ public:
|
||||
run()
|
||||
{
|
||||
m_face.setInterestFilter("/example/testApp/randomData",
|
||||
std::bind(&Producer::onInterest, this, _1, _2),
|
||||
std::bind(&Producer::onInterest, this, _2),
|
||||
nullptr, // RegisterPrefixSuccessCallback is optional
|
||||
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));
|
||||
[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
|
||||
// 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
|
||||
//
|
||||
@@ -91,7 +90,7 @@ 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();
|
||||
}
|
||||
|
||||
|
||||
+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',
|
||||
|
||||
+84
-22
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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).
|
||||
*
|
||||
@@ -24,13 +24,6 @@
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -51,10 +44,25 @@ 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) {
|
||||
@@ -136,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) {
|
||||
@@ -184,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())) {
|
||||
@@ -211,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;
|
||||
@@ -269,20 +303,18 @@ Data::setContent(span<const uint8_t> value)
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setContent(const uint8_t* value, size_t length)
|
||||
Data::setContent(std::string_view value)
|
||||
{
|
||||
if (value == nullptr && length != 0) {
|
||||
NDN_THROW(std::invalid_argument("Content buffer cannot be nullptr"));
|
||||
}
|
||||
|
||||
return setContent(make_span(value, length));
|
||||
m_content = makeStringBlock(tlv::Content, value);
|
||||
resetWire();
|
||||
return *this;
|
||||
}
|
||||
|
||||
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));
|
||||
@@ -293,8 +325,10 @@ Data::setContent(ConstBufferPtr value)
|
||||
Data&
|
||||
Data::unsetContent()
|
||||
{
|
||||
m_content = {};
|
||||
resetWire();
|
||||
if (m_content.isValid()) {
|
||||
m_content = {};
|
||||
resetWire();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -306,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));
|
||||
@@ -332,6 +374,25 @@ Data::extractSignedRanges() const
|
||||
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)
|
||||
{
|
||||
@@ -353,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));
|
||||
@@ -389,3 +450,4 @@ operator<<(std::ostream& os, const Data& data)
|
||||
}
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
+121
-63
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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,8 +31,9 @@
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** @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>
|
||||
{
|
||||
@@ -94,18 +95,21 @@ public:
|
||||
const Block&
|
||||
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
|
||||
@@ -113,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
|
||||
@@ -129,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
|
||||
@@ -143,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
|
||||
@@ -159,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
|
||||
@@ -176,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.
|
||||
@@ -187,41 +198,42 @@ public: // Data fields
|
||||
setContent(const Block& block);
|
||||
|
||||
/**
|
||||
* @brief Set Content by copying from a contiguous sequence of bytes
|
||||
* @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
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
*/
|
||||
Data&
|
||||
setContent(span<const uint8_t> value);
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @deprecated Use setContent(span<const uint8_t>)
|
||||
* @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.
|
||||
*/
|
||||
[[deprecated("use the overload that takes a span<>")]]
|
||||
Data&
|
||||
setContent(const uint8_t* value, size_t length);
|
||||
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 nullptr
|
||||
* @return a reference to this Data, to allow chaining
|
||||
* @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 SignatureInfo
|
||||
/**
|
||||
* @brief Get the `SignatureInfo` element.
|
||||
*/
|
||||
const SignatureInfo&
|
||||
getSignatureInfo() const noexcept
|
||||
@@ -229,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
|
||||
@@ -249,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
|
||||
@@ -287,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
|
||||
@@ -306,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();
|
||||
@@ -327,6 +381,9 @@ 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
|
||||
@@ -355,3 +412,4 @@ operator!=(const Data& lhs, const Data& rhs)
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_CXX_DATA_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -22,19 +22,8 @@
|
||||
#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 asio
|
||||
} // namespace boost
|
||||
} // namespace boost::asio
|
||||
|
||||
#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-2021 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).
|
||||
*
|
||||
@@ -24,10 +24,13 @@
|
||||
|
||||
#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_CXX_DETAIL_CANCEL_HANDLE_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -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_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-2021 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).
|
||||
*
|
||||
@@ -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_CXX_DETAIL_CF_STRING_OSX_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -30,9 +30,9 @@
|
||||
|
||||
#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,13 +68,9 @@ 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::to_string;
|
||||
using namespace std::string_literals;
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
@@ -112,7 +107,6 @@ NDN_CXX_SPECIALIZE_BOOST_IS_PLACEHOLDER_FOR_STD_PLACEHOLDER(9)
|
||||
/// \endcond
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
|
||||
namespace ndn {
|
||||
|
||||
@@ -1,727 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2016-2018 Martin Moene
|
||||
//
|
||||
// https://github.com/martinmoene/any-lite
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NONSTD_ANY_LITE_HPP
|
||||
#define NONSTD_ANY_LITE_HPP
|
||||
|
||||
#define any_lite_MAJOR 0
|
||||
#define any_lite_MINOR 4
|
||||
#define any_lite_PATCH 0
|
||||
|
||||
#define any_lite_VERSION any_STRINGIFY(any_lite_MAJOR) "." any_STRINGIFY(any_lite_MINOR) "." any_STRINGIFY(any_lite_PATCH)
|
||||
|
||||
#define any_STRINGIFY( x ) any_STRINGIFY_( x )
|
||||
#define any_STRINGIFY_( x ) #x
|
||||
|
||||
// any-lite configuration:
|
||||
|
||||
#define any_ANY_DEFAULT 0
|
||||
#define any_ANY_NONSTD 1
|
||||
#define any_ANY_STD 2
|
||||
|
||||
// tweak header support:
|
||||
|
||||
#ifdef __has_include
|
||||
# if __has_include(<nonstd/any.tweak.hpp>)
|
||||
# include <nonstd/any.tweak.hpp>
|
||||
# endif
|
||||
#define any_HAVE_TWEAK_HEADER 1
|
||||
#else
|
||||
#define any_HAVE_TWEAK_HEADER 0
|
||||
//# pragma message("any.hpp: Note: Tweak header not supported.")
|
||||
#endif
|
||||
|
||||
// any selection and configuration:
|
||||
|
||||
#if !defined( any_CONFIG_SELECT_ANY )
|
||||
# define any_CONFIG_SELECT_ANY ( any_HAVE_STD_ANY ? any_ANY_STD : any_ANY_NONSTD )
|
||||
#endif
|
||||
|
||||
// Control presence of exception handling (try and auto discover):
|
||||
|
||||
#ifndef any_CONFIG_NO_EXCEPTIONS
|
||||
# if _MSC_VER
|
||||
# include <cstddef> // for _HAS_EXCEPTIONS
|
||||
# endif
|
||||
# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
|
||||
# define any_CONFIG_NO_EXCEPTIONS 0
|
||||
# else
|
||||
# define any_CONFIG_NO_EXCEPTIONS 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// C++ language version detection (C++20 is speculative):
|
||||
// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
|
||||
|
||||
#ifndef any_CPLUSPLUS
|
||||
# if defined(_MSVC_LANG ) && !defined(__clang__)
|
||||
# define any_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
|
||||
# else
|
||||
# define any_CPLUSPLUS __cplusplus
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define any_CPP98_OR_GREATER ( any_CPLUSPLUS >= 199711L )
|
||||
#define any_CPP11_OR_GREATER ( any_CPLUSPLUS >= 201103L )
|
||||
#define any_CPP14_OR_GREATER ( any_CPLUSPLUS >= 201402L )
|
||||
#define any_CPP17_OR_GREATER ( any_CPLUSPLUS >= 201703L )
|
||||
#define any_CPP20_OR_GREATER ( any_CPLUSPLUS >= 202000L )
|
||||
|
||||
// Use C++17 std::any if available and requested:
|
||||
|
||||
#if any_CPP17_OR_GREATER && defined(__has_include )
|
||||
# if __has_include( <any> )
|
||||
# define any_HAVE_STD_ANY 1
|
||||
# else
|
||||
# define any_HAVE_STD_ANY 0
|
||||
# endif
|
||||
#else
|
||||
# define any_HAVE_STD_ANY 0
|
||||
#endif
|
||||
|
||||
#define any_USES_STD_ANY ( (any_CONFIG_SELECT_ANY == any_ANY_STD) || ((any_CONFIG_SELECT_ANY == any_ANY_DEFAULT) && any_HAVE_STD_ANY) )
|
||||
|
||||
//
|
||||
// in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite:
|
||||
//
|
||||
|
||||
#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
|
||||
#define nonstd_lite_HAVE_IN_PLACE_TYPES 1
|
||||
|
||||
// C++17 std::in_place in <utility>:
|
||||
|
||||
#if any_CPP17_OR_GREATER
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace nonstd {
|
||||
|
||||
using std::in_place;
|
||||
using std::in_place_type;
|
||||
using std::in_place_index;
|
||||
using std::in_place_t;
|
||||
using std::in_place_type_t;
|
||||
using std::in_place_index_t;
|
||||
|
||||
#define nonstd_lite_in_place_t( T) std::in_place_t
|
||||
#define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
|
||||
#define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
|
||||
|
||||
#define nonstd_lite_in_place( T) std::in_place_t{}
|
||||
#define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
|
||||
#define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
|
||||
|
||||
} // namespace nonstd
|
||||
|
||||
#else // any_CPP17_OR_GREATER
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace nonstd {
|
||||
namespace detail {
|
||||
|
||||
template< class T >
|
||||
struct in_place_type_tag {};
|
||||
|
||||
template< std::size_t K >
|
||||
struct in_place_index_tag {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
struct in_place_t {};
|
||||
|
||||
template< class T >
|
||||
inline in_place_t in_place( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
|
||||
{
|
||||
return in_place_t();
|
||||
}
|
||||
|
||||
template< std::size_t K >
|
||||
inline in_place_t in_place( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
|
||||
{
|
||||
return in_place_t();
|
||||
}
|
||||
|
||||
template< class T >
|
||||
inline in_place_t in_place_type( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
|
||||
{
|
||||
return in_place_t();
|
||||
}
|
||||
|
||||
template< std::size_t K >
|
||||
inline in_place_t in_place_index( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
|
||||
{
|
||||
return in_place_t();
|
||||
}
|
||||
|
||||
// mimic templated typedef:
|
||||
|
||||
#define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
|
||||
#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
|
||||
#define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
|
||||
|
||||
#define nonstd_lite_in_place( T) nonstd::in_place_type<T>
|
||||
#define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
|
||||
#define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
|
||||
|
||||
} // namespace nonstd
|
||||
|
||||
#endif // any_CPP17_OR_GREATER
|
||||
#endif // nonstd_lite_HAVE_IN_PLACE_TYPES
|
||||
|
||||
//
|
||||
// Using std::any:
|
||||
//
|
||||
|
||||
#if any_USES_STD_ANY
|
||||
|
||||
#include <any>
|
||||
#include <utility>
|
||||
|
||||
namespace nonstd {
|
||||
|
||||
using std::any;
|
||||
using std::any_cast;
|
||||
using std::make_any;
|
||||
using std::swap;
|
||||
using std::bad_any_cast;
|
||||
}
|
||||
|
||||
#else // any_USES_STD_ANY
|
||||
|
||||
#include <utility>
|
||||
|
||||
// Compiler versions:
|
||||
//
|
||||
// MSVC++ 6.0 _MSC_VER == 1200 any_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
|
||||
// MSVC++ 7.0 _MSC_VER == 1300 any_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
|
||||
// MSVC++ 7.1 _MSC_VER == 1310 any_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
|
||||
// MSVC++ 8.0 _MSC_VER == 1400 any_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
|
||||
// MSVC++ 9.0 _MSC_VER == 1500 any_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
|
||||
// MSVC++ 10.0 _MSC_VER == 1600 any_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
|
||||
// MSVC++ 11.0 _MSC_VER == 1700 any_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
|
||||
// MSVC++ 12.0 _MSC_VER == 1800 any_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
|
||||
// MSVC++ 14.0 _MSC_VER == 1900 any_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
|
||||
// MSVC++ 14.1 _MSC_VER >= 1910 any_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
|
||||
// MSVC++ 14.2 _MSC_VER >= 1920 any_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
|
||||
|
||||
#if defined(_MSC_VER ) && !defined(__clang__)
|
||||
# define any_COMPILER_MSVC_VER (_MSC_VER )
|
||||
# define any_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
|
||||
#else
|
||||
# define any_COMPILER_MSVC_VER 0
|
||||
# define any_COMPILER_MSVC_VERSION 0
|
||||
#endif
|
||||
|
||||
#define any_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
|
||||
|
||||
#if defined(__clang__)
|
||||
# define any_COMPILER_CLANG_VERSION any_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
|
||||
#else
|
||||
# define any_COMPILER_CLANG_VERSION 0
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
# define any_COMPILER_GNUC_VERSION any_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
|
||||
#else
|
||||
# define any_COMPILER_GNUC_VERSION 0
|
||||
#endif
|
||||
|
||||
// half-open range [lo..hi):
|
||||
//#define any_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
|
||||
|
||||
// Presence of language and library features:
|
||||
|
||||
#define any_HAVE( feature ) ( any_HAVE_##feature )
|
||||
|
||||
#ifdef _HAS_CPP0X
|
||||
# define any_HAS_CPP0X _HAS_CPP0X
|
||||
#else
|
||||
# define any_HAS_CPP0X 0
|
||||
#endif
|
||||
|
||||
#define any_CPP11_90 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1500)
|
||||
#define any_CPP11_100 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1600)
|
||||
#define any_CPP11_120 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1800)
|
||||
#define any_CPP11_140 (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VER >= 1900)
|
||||
|
||||
#define any_CPP14_000 (any_CPP14_OR_GREATER)
|
||||
#define any_CPP17_000 (any_CPP17_OR_GREATER)
|
||||
|
||||
// Presence of C++11 language features:
|
||||
|
||||
#define any_HAVE_CONSTEXPR_11 any_CPP11_140
|
||||
#define any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG \
|
||||
any_CPP11_120
|
||||
#define any_HAVE_INITIALIZER_LIST any_CPP11_120
|
||||
#define any_HAVE_NOEXCEPT any_CPP11_140
|
||||
#define any_HAVE_NULLPTR any_CPP11_100
|
||||
#define any_HAVE_TYPE_TRAITS any_CPP11_90
|
||||
#define any_HAVE_STATIC_ASSERT any_CPP11_100
|
||||
#define any_HAVE_ADD_CONST any_CPP11_90
|
||||
#define any_HAVE_OVERRIDE any_CPP11_90
|
||||
#define any_HAVE_REMOVE_REFERENCE any_CPP11_90
|
||||
|
||||
#define any_HAVE_TR1_ADD_CONST (!! any_COMPILER_GNUC_VERSION )
|
||||
#define any_HAVE_TR1_REMOVE_REFERENCE (!! any_COMPILER_GNUC_VERSION )
|
||||
#define any_HAVE_TR1_TYPE_TRAITS (!! any_COMPILER_GNUC_VERSION )
|
||||
|
||||
// Presence of C++14 language features:
|
||||
|
||||
#define any_HAVE_CONSTEXPR_14 any_CPP14_000
|
||||
|
||||
// Presence of C++17 language features:
|
||||
|
||||
#define any_HAVE_NODISCARD any_CPP17_000
|
||||
|
||||
// Presence of C++ language features:
|
||||
|
||||
#if any_HAVE_CONSTEXPR_11
|
||||
# define any_constexpr constexpr
|
||||
#else
|
||||
# define any_constexpr /*constexpr*/
|
||||
#endif
|
||||
|
||||
#if any_HAVE_CONSTEXPR_14
|
||||
# define any_constexpr14 constexpr
|
||||
#else
|
||||
# define any_constexpr14 /*constexpr*/
|
||||
#endif
|
||||
|
||||
#if any_HAVE_NOEXCEPT
|
||||
# define any_noexcept noexcept
|
||||
#else
|
||||
# define any_noexcept /*noexcept*/
|
||||
#endif
|
||||
|
||||
#if any_HAVE_NULLPTR
|
||||
# define any_nullptr nullptr
|
||||
#else
|
||||
# define any_nullptr NULL
|
||||
#endif
|
||||
|
||||
#if any_HAVE_NODISCARD
|
||||
# define any_nodiscard [[nodiscard]]
|
||||
#else
|
||||
# define any_nodiscard /*[[nodiscard]]*/
|
||||
#endif
|
||||
|
||||
#if any_HAVE_OVERRIDE
|
||||
# define any_override override
|
||||
#else
|
||||
# define any_override /*override*/
|
||||
#endif
|
||||
|
||||
// additional includes:
|
||||
|
||||
#if any_CONFIG_NO_EXCEPTIONS
|
||||
# include <cassert>
|
||||
#else
|
||||
# include <typeinfo>
|
||||
#endif
|
||||
|
||||
#if ! any_HAVE_NULLPTR
|
||||
# include <cstddef>
|
||||
#endif
|
||||
|
||||
#if any_HAVE_INITIALIZER_LIST
|
||||
# include <initializer_list>
|
||||
#endif
|
||||
|
||||
#if any_HAVE_TYPE_TRAITS
|
||||
# include <type_traits>
|
||||
#elif any_HAVE_TR1_TYPE_TRAITS
|
||||
# include <tr1/type_traits>
|
||||
#endif
|
||||
|
||||
// Method enabling
|
||||
|
||||
#if any_CPP11_OR_GREATER
|
||||
|
||||
#define any_REQUIRES_0(...) \
|
||||
template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
|
||||
|
||||
#define any_REQUIRES_T(...) \
|
||||
, typename std::enable_if< (__VA_ARGS__), int >::type = 0
|
||||
|
||||
#define any_REQUIRES_R(R, ...) \
|
||||
typename std::enable_if<__VA_ARGS__, R>::type
|
||||
|
||||
#define any_REQUIRES_A(...) \
|
||||
, typename std::enable_if<__VA_ARGS__, void*>::type = nullptr
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// any:
|
||||
//
|
||||
|
||||
namespace nonstd { namespace any_lite {
|
||||
|
||||
// C++11 emulation:
|
||||
|
||||
namespace std11 {
|
||||
|
||||
#if any_HAVE_ADD_CONST
|
||||
|
||||
using std::add_const;
|
||||
|
||||
#elif any_HAVE_TR1_ADD_CONST
|
||||
|
||||
using std::tr1::add_const;
|
||||
|
||||
#else
|
||||
|
||||
template< class T > struct add_const { typedef const T type; };
|
||||
|
||||
#endif // any_HAVE_ADD_CONST
|
||||
|
||||
#if any_HAVE_REMOVE_REFERENCE
|
||||
|
||||
using std::remove_reference;
|
||||
|
||||
#elif any_HAVE_TR1_REMOVE_REFERENCE
|
||||
|
||||
using std::tr1::remove_reference;
|
||||
|
||||
#else
|
||||
|
||||
template< class T > struct remove_reference { typedef T type; };
|
||||
template< class T > struct remove_reference<T&> { typedef T type; };
|
||||
|
||||
#endif // any_HAVE_REMOVE_REFERENCE
|
||||
|
||||
} // namespace std11
|
||||
|
||||
namespace detail {
|
||||
|
||||
// for any_REQUIRES_T
|
||||
|
||||
/*enum*/ class enabler{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if ! any_CONFIG_NO_EXCEPTIONS
|
||||
|
||||
class bad_any_cast : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
#if any_CPP11_OR_GREATER
|
||||
virtual const char* what() const any_noexcept any_override
|
||||
#else
|
||||
virtual const char* what() const throw()
|
||||
#endif
|
||||
{
|
||||
return "any-lite: bad any_cast";
|
||||
}
|
||||
};
|
||||
|
||||
#endif // any_CONFIG_NO_EXCEPTIONS
|
||||
|
||||
class any
|
||||
{
|
||||
public:
|
||||
any_constexpr any() any_noexcept
|
||||
: content( any_nullptr )
|
||||
{}
|
||||
|
||||
any( any const & other )
|
||||
: content( other.content ? other.content->clone() : any_nullptr )
|
||||
{}
|
||||
|
||||
#if any_CPP11_OR_GREATER
|
||||
|
||||
any( any && other ) any_noexcept
|
||||
: content( std::move( other.content ) )
|
||||
{
|
||||
other.content = any_nullptr;
|
||||
}
|
||||
|
||||
template<
|
||||
class ValueType, class T = typename std::decay<ValueType>::type
|
||||
any_REQUIRES_T( ! std::is_same<T, any>::value )
|
||||
>
|
||||
any( ValueType && value ) any_noexcept
|
||||
: content( new holder<T>( std::forward<ValueType>( value ) ) )
|
||||
{}
|
||||
|
||||
template<
|
||||
class T, class... Args
|
||||
any_REQUIRES_T( std::is_constructible<T, Args&&...>::value )
|
||||
>
|
||||
explicit any( nonstd_lite_in_place_type_t(T), Args&&... args )
|
||||
: content( new holder<T>( T( std::forward<Args>(args)... ) ) )
|
||||
{}
|
||||
|
||||
template<
|
||||
class T, class U, class... Args
|
||||
any_REQUIRES_T( std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value )
|
||||
>
|
||||
explicit any( nonstd_lite_in_place_type_t(T), std::initializer_list<U> il, Args&&... args )
|
||||
: content( new holder<T>( T( il, std::forward<Args>(args)... ) ) )
|
||||
{}
|
||||
|
||||
#else
|
||||
|
||||
template< class ValueType >
|
||||
any( ValueType const & value )
|
||||
: content( new holder<ValueType>( value ) )
|
||||
{}
|
||||
|
||||
#endif // any_CPP11_OR_GREATER
|
||||
|
||||
~any()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
any & operator=( any const & other )
|
||||
{
|
||||
any( other ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if any_CPP11_OR_GREATER
|
||||
|
||||
any & operator=( any && other ) any_noexcept
|
||||
{
|
||||
any( std::move( other ) ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<
|
||||
class ValueType, class T = typename std::decay<ValueType>::type
|
||||
any_REQUIRES_T( ! std::is_same<T, any>::value )
|
||||
>
|
||||
any & operator=( T && value )
|
||||
{
|
||||
any( std::move( value ) ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< class T, class... Args >
|
||||
void emplace( Args && ... args )
|
||||
{
|
||||
any( T( std::forward<Args>(args)... ) ).swap( *this );
|
||||
}
|
||||
|
||||
template<
|
||||
class T, class U, class... Args
|
||||
any_REQUIRES_T( std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value )
|
||||
>
|
||||
void emplace( std::initializer_list<U> il, Args&&... args )
|
||||
{
|
||||
any( T( il, std::forward<Args>(args)... ) ).swap( *this );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template< class ValueType >
|
||||
any & operator=( ValueType const & value )
|
||||
{
|
||||
any( value ).swap( *this );
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif // any_CPP11_OR_GREATER
|
||||
|
||||
void reset() any_noexcept
|
||||
{
|
||||
delete content; content = any_nullptr;
|
||||
}
|
||||
|
||||
void swap( any & other ) any_noexcept
|
||||
{
|
||||
std::swap( content, other.content );
|
||||
}
|
||||
|
||||
bool has_value() const any_noexcept
|
||||
{
|
||||
return content != any_nullptr;
|
||||
}
|
||||
|
||||
const std::type_info & type() const any_noexcept
|
||||
{
|
||||
return has_value() ? content->type() : typeid( void );
|
||||
}
|
||||
|
||||
//
|
||||
// non-standard:
|
||||
//
|
||||
|
||||
template< class ValueType >
|
||||
const ValueType * to_ptr() const
|
||||
{
|
||||
return &( static_cast<holder<ValueType> *>( content )->held );
|
||||
}
|
||||
|
||||
template< class ValueType >
|
||||
ValueType * to_ptr()
|
||||
{
|
||||
return &( static_cast<holder<ValueType> *>( content )->held );
|
||||
}
|
||||
|
||||
private:
|
||||
class placeholder
|
||||
{
|
||||
public:
|
||||
virtual ~placeholder()
|
||||
{
|
||||
}
|
||||
|
||||
virtual std::type_info const & type() const = 0;
|
||||
|
||||
virtual placeholder * clone() const = 0;
|
||||
};
|
||||
|
||||
template< typename ValueType >
|
||||
class holder : public placeholder
|
||||
{
|
||||
public:
|
||||
holder( ValueType const & value )
|
||||
: held( value )
|
||||
{}
|
||||
|
||||
#if any_CPP11_OR_GREATER
|
||||
holder( ValueType && value )
|
||||
: held( std::move( value ) )
|
||||
{}
|
||||
#endif
|
||||
|
||||
virtual std::type_info const & type() const any_override
|
||||
{
|
||||
return typeid( ValueType );
|
||||
}
|
||||
|
||||
virtual placeholder * clone() const any_override
|
||||
{
|
||||
return new holder( held );
|
||||
}
|
||||
|
||||
ValueType held;
|
||||
};
|
||||
|
||||
placeholder * content;
|
||||
};
|
||||
|
||||
inline void swap( any & x, any & y ) any_noexcept
|
||||
{
|
||||
x.swap( y );
|
||||
}
|
||||
|
||||
#if any_CPP11_OR_GREATER
|
||||
|
||||
template< class T, class ...Args >
|
||||
inline any make_any( Args&& ...args )
|
||||
{
|
||||
return any( nonstd_lite_in_place_type(T), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template< class T, class U, class ...Args >
|
||||
inline any make_any( std::initializer_list<U> il, Args&& ...args )
|
||||
{
|
||||
return any( nonstd_lite_in_place_type(T), il, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#endif // any_CPP11_OR_GREATER
|
||||
|
||||
template<
|
||||
class ValueType
|
||||
#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
|
||||
// any_REQUIRES_T(...) Allow for VC120 (VS2013):
|
||||
, typename = typename std::enable_if< (std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value), nonstd::any_lite::detail::enabler >::type
|
||||
#endif
|
||||
>
|
||||
any_nodiscard inline ValueType any_cast( any const & operand )
|
||||
{
|
||||
const ValueType * result = any_cast< typename std11::add_const< typename std11::remove_reference<ValueType>::type >::type >( &operand );
|
||||
|
||||
#if any_CONFIG_NO_EXCEPTIONS
|
||||
assert( result );
|
||||
#else
|
||||
if ( ! result )
|
||||
{
|
||||
throw bad_any_cast();
|
||||
}
|
||||
#endif
|
||||
|
||||
return *result;
|
||||
}
|
||||
|
||||
template<
|
||||
class ValueType
|
||||
#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
|
||||
// any_REQUIRES_T(...) Allow for VC120 (VS2013):
|
||||
, typename = typename std::enable_if< (std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value), nonstd::any_lite::detail::enabler >::type
|
||||
#endif
|
||||
>
|
||||
any_nodiscard inline ValueType any_cast( any & operand )
|
||||
{
|
||||
const ValueType * result = any_cast< typename std11::remove_reference<ValueType>::type >( &operand );
|
||||
|
||||
#if any_CONFIG_NO_EXCEPTIONS
|
||||
assert( result );
|
||||
#else
|
||||
if ( ! result )
|
||||
{
|
||||
throw bad_any_cast();
|
||||
}
|
||||
#endif
|
||||
|
||||
return *result;
|
||||
}
|
||||
|
||||
#if any_CPP11_OR_GREATER
|
||||
|
||||
template<
|
||||
class ValueType
|
||||
#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
|
||||
any_REQUIRES_T( std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value )
|
||||
#endif
|
||||
>
|
||||
any_nodiscard inline ValueType any_cast( any && operand )
|
||||
{
|
||||
const ValueType * result = any_cast< typename std11::remove_reference<ValueType>::type >( &operand );
|
||||
|
||||
#if any_CONFIG_NO_EXCEPTIONS
|
||||
assert( result );
|
||||
#else
|
||||
if ( ! result )
|
||||
{
|
||||
throw bad_any_cast();
|
||||
}
|
||||
#endif
|
||||
|
||||
return *result;
|
||||
}
|
||||
|
||||
#endif // any_CPP11_OR_GREATER
|
||||
|
||||
template< class ValueType >
|
||||
any_nodiscard inline ValueType const * any_cast( any const * operand ) any_noexcept
|
||||
{
|
||||
return operand != any_nullptr && operand->type() == typeid(ValueType) ? operand->to_ptr<ValueType>() : any_nullptr;
|
||||
}
|
||||
|
||||
template<class ValueType >
|
||||
any_nodiscard inline ValueType * any_cast( any * operand ) any_noexcept
|
||||
{
|
||||
return operand != any_nullptr && operand->type() == typeid(ValueType) ? operand->to_ptr<ValueType>() : any_nullptr;
|
||||
}
|
||||
|
||||
} // namespace any_lite
|
||||
|
||||
using namespace any_lite;
|
||||
|
||||
} // namespace nonstd
|
||||
|
||||
#endif // any_USES_STD_ANY
|
||||
|
||||
#endif // NONSTD_ANY_LITE_HPP
|
||||
File diff suppressed because it is too large.
Load diff
@@ -45,11 +45,15 @@
|
||||
# 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
|
||||
@@ -64,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
|
||||
@@ -83,6 +91,10 @@
|
||||
//
|
||||
// Using std <scope>:
|
||||
//
|
||||
// ToDo:
|
||||
// - choose <scope> or <experimental/scope>.
|
||||
// - use correct namespace in using below.
|
||||
//
|
||||
|
||||
#if scope_USES_STD_SCOPE
|
||||
|
||||
@@ -259,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
|
||||
@@ -558,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:
|
||||
//
|
||||
@@ -646,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
|
||||
@@ -659,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
|
||||
@@ -671,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;
|
||||
@@ -705,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
|
||||
@@ -714,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
|
||||
@@ -729,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:
|
||||
@@ -763,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
|
||||
@@ -772,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
|
||||
@@ -787,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 )
|
||||
@@ -818,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 )
|
||||
{
|
||||
@@ -825,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 )
|
||||
{
|
||||
@@ -832,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 )
|
||||
{
|
||||
@@ -1196,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 )
|
||||
@@ -1212,7 +1255,7 @@ struct on_fail_policy
|
||||
|
||||
bool perform()
|
||||
{
|
||||
return ucount_ < std17::uncaught_exceptions();
|
||||
return ucount_ < detail::uncaught_exceptions();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1221,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 )
|
||||
@@ -1237,7 +1280,7 @@ struct on_success_policy
|
||||
|
||||
bool perform()
|
||||
{
|
||||
return ucount_ >= std17::uncaught_exceptions();
|
||||
return ucount_ >= detail::uncaught_exceptions();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
# error Please define none or one of span_CONFIG_CONTRACT_VIOLATION_THROWS and span_CONFIG_CONTRACT_VIOLATION_TERMINATES to 1, but not both.
|
||||
#endif
|
||||
|
||||
// C++ language version detection (C++20 is speculative):
|
||||
// C++ language version detection (C++23 is speculative):
|
||||
// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
|
||||
|
||||
#ifndef span_CPLUSPLUS
|
||||
@@ -190,7 +190,8 @@
|
||||
#define span_CPP11_OR_GREATER ( span_CPLUSPLUS >= 201103L )
|
||||
#define span_CPP14_OR_GREATER ( span_CPLUSPLUS >= 201402L )
|
||||
#define span_CPP17_OR_GREATER ( span_CPLUSPLUS >= 201703L )
|
||||
#define span_CPP20_OR_GREATER ( span_CPLUSPLUS >= 202000L )
|
||||
#define span_CPP20_OR_GREATER ( span_CPLUSPLUS >= 202002L )
|
||||
#define span_CPP23_OR_GREATER ( span_CPLUSPLUS >= 202300L )
|
||||
|
||||
// C++ language version (represent 98 as 3):
|
||||
|
||||
|
||||
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-2021 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).
|
||||
*
|
||||
@@ -26,17 +26,17 @@
|
||||
|
||||
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);
|
||||
|
||||
+20
-16
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -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());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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 ----
|
||||
|
||||
@@ -66,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 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();
|
||||
}
|
||||
|
||||
// ---- string ----
|
||||
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value)
|
||||
{
|
||||
return prependBinaryBlock(encoder, 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");
|
||||
@@ -133,7 +103,7 @@ prependDoubleBlock(EncodingImpl<TAG>& encoder, uint32_t type, double value)
|
||||
{
|
||||
uint64_t temp = 0;
|
||||
std::memcpy(&temp, &value, 8);
|
||||
endian::native_to_big_inplace(temp);
|
||||
boost::endian::native_to_big_inplace(temp);
|
||||
return prependBinaryBlock(encoder, type, {reinterpret_cast<const uint8_t*>(&temp), 8});
|
||||
}
|
||||
|
||||
@@ -161,17 +131,7 @@ 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 ----
|
||||
@@ -205,6 +165,27 @@ makeBinaryBlock(uint32_t type, span<const uint8_t> value)
|
||||
return encoder.block();
|
||||
}
|
||||
|
||||
// ---- string ----
|
||||
|
||||
template<Tag TAG>
|
||||
size_t
|
||||
prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, std::string_view value)
|
||||
{
|
||||
return prependBinaryBlock(encoder, type, {reinterpret_cast<const uint8_t*>(value.data()), value.size()});
|
||||
}
|
||||
|
||||
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>
|
||||
@@ -212,11 +193,11 @@ size_t
|
||||
prependBlock(EncodingImpl<TAG>& encoder, const Block& block)
|
||||
{
|
||||
if (block.hasWire()) {
|
||||
return encoder.prependBytes({block.wire(), block.size()});
|
||||
return encoder.prependBytes(block);
|
||||
}
|
||||
else {
|
||||
// FIXME: blindly calling Block::value() is not safe if the value is not wire-encoded
|
||||
return prependBinaryBlock(encoder, block.type(), {block.value(), block.value_size()});
|
||||
// FIXME: blindly calling Block::value_bytes() is not safe if the value is not wire-encoded
|
||||
return prependBinaryBlock(encoder, block.type(), block.value_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,5 +207,4 @@ prependBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, const Block&);
|
||||
template size_t
|
||||
prependBlock<EncoderTag>(EncodingImpl<EncoderTag>&, const Block&);
|
||||
|
||||
} // namespace encoding
|
||||
} // namespace ndn
|
||||
} // namespace ndn::encoding
|
||||
+117
-131
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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).
|
||||
*
|
||||
@@ -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
|
||||
@@ -207,106 +175,124 @@ prependBinaryBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, span<const u
|
||||
Block
|
||||
makeBinaryBlock(uint32_t type, span<const uint8_t> value);
|
||||
|
||||
/** @brief Create a TLV block copying the TLV-VALUE from a raw buffer.
|
||||
* @param type TLV-TYPE number
|
||||
* @param value raw buffer as TLV-VALUE
|
||||
* @param length length of value buffer
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use the overload that takes a span<>")]]
|
||||
inline Block
|
||||
makeBinaryBlock(uint32_t type, const uint8_t* value, size_t length)
|
||||
{
|
||||
return makeBinaryBlock(type, {value, length});
|
||||
}
|
||||
|
||||
/** @brief Create a TLV block copying the TLV-VALUE from a raw buffer.
|
||||
* @param type TLV-TYPE number
|
||||
* @param value raw buffer as TLV-VALUE
|
||||
* @param length length of value buffer
|
||||
* @deprecated
|
||||
*/
|
||||
inline Block
|
||||
makeBinaryBlock(uint32_t type, const char* value, size_t length)
|
||||
{
|
||||
return makeBinaryBlock(type, {reinterpret_cast<const uint8_t*>(value), length});
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
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 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
|
||||
/**
|
||||
* @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
|
||||
@@ -407,13 +393,13 @@ makeNestedBlock(uint32_t type, I first, I last)
|
||||
|
||||
} // 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
|
||||
|
||||
+57
-61
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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 ----
|
||||
|
||||
@@ -111,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)
|
||||
{
|
||||
@@ -130,11 +133,6 @@ Block::Block(ConstBufferPtr buffer, uint32_t type,
|
||||
{
|
||||
}
|
||||
|
||||
Block::Block(const uint8_t* buf, size_t bufSize)
|
||||
: Block(make_span(buf, bufSize))
|
||||
{
|
||||
}
|
||||
|
||||
Block::Block(uint32_t type)
|
||||
: m_type(type)
|
||||
, m_size(tlv::sizeOfVarNumber(m_type) + tlv::sizeOfVarNumber(0))
|
||||
@@ -173,22 +171,22 @@ Block::fromBuffer(ConstBufferPtr buffer, size_t offset)
|
||||
uint32_t type = 0;
|
||||
bool isOk = tlv::readType(pos, end, type);
|
||||
if (!isOk) {
|
||||
return std::make_tuple(false, Block());
|
||||
return {false, {}};
|
||||
}
|
||||
|
||||
uint64_t length = 0;
|
||||
isOk = tlv::readVarNumber(pos, end, length);
|
||||
if (!isOk) {
|
||||
return std::make_tuple(false, Block());
|
||||
return {false, {}};
|
||||
}
|
||||
// pos now points to TLV-VALUE
|
||||
|
||||
BOOST_ASSERT(pos <= end);
|
||||
if (length > static_cast<uint64_t>(std::distance(pos, end))) {
|
||||
return std::make_tuple(false, Block());
|
||||
return {false, {}};
|
||||
}
|
||||
|
||||
return std::make_tuple(true, Block(std::move(buffer), type, begin, pos + length, pos, pos + length));
|
||||
return {true, Block(std::move(buffer), type, begin, pos + length, pos, pos + length)};
|
||||
}
|
||||
|
||||
std::tuple<bool, Block>
|
||||
@@ -200,31 +198,24 @@ Block::fromBuffer(span<const uint8_t> buffer)
|
||||
uint32_t type = 0;
|
||||
bool isOk = tlv::readType(pos, end, type);
|
||||
if (!isOk) {
|
||||
return std::make_tuple(false, Block());
|
||||
return {false, {}};
|
||||
}
|
||||
uint64_t length = 0;
|
||||
isOk = tlv::readVarNumber(pos, end, length);
|
||||
if (!isOk) {
|
||||
return std::make_tuple(false, Block());
|
||||
return {false, {}};
|
||||
}
|
||||
// pos now points to TLV-VALUE
|
||||
|
||||
BOOST_ASSERT(pos <= end);
|
||||
if (length > static_cast<uint64_t>(std::distance(pos, end))) {
|
||||
return std::make_tuple(false, Block());
|
||||
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 std::make_tuple(true, Block(b, type, b->begin(), b->end(),
|
||||
std::prev(b->end(), length), b->end()));
|
||||
}
|
||||
|
||||
std::tuple<bool, Block>
|
||||
Block::fromBuffer(const uint8_t* buf, size_t bufSize)
|
||||
{
|
||||
return fromBuffer({buf, bufSize});
|
||||
return {true, Block(b, type, b->begin(), b->end(), std::prev(b->end(), length), b->end())};
|
||||
}
|
||||
|
||||
Block
|
||||
@@ -274,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())
|
||||
@@ -283,7 +274,7 @@ Block::begin() const
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
Buffer::const_iterator
|
||||
Block::const_iterator
|
||||
Block::end() const
|
||||
{
|
||||
if (!hasWire())
|
||||
@@ -293,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"));
|
||||
@@ -319,12 +310,6 @@ Block::value() const noexcept
|
||||
return value_size() > 0 ? &*m_valueBegin : nullptr;
|
||||
}
|
||||
|
||||
size_t
|
||||
Block::value_size() const noexcept
|
||||
{
|
||||
return hasValue() ? static_cast<size_t>(m_valueEnd - m_valueBegin) : 0;
|
||||
}
|
||||
|
||||
Block
|
||||
Block::blockFromValue() const
|
||||
{
|
||||
@@ -428,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
|
||||
@@ -475,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)
|
||||
{
|
||||
@@ -486,47 +477,50 @@ Block::insert(Block::element_const_iterator pos, const Block& element)
|
||||
|
||||
Block::operator boost::asio::const_buffer() const
|
||||
{
|
||||
return {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;
|
||||
@@ -549,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
|
||||
+177
-118
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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).
|
||||
*
|
||||
@@ -29,21 +29,23 @@
|
||||
#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
|
||||
* @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;
|
||||
@@ -121,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
|
||||
@@ -136,16 +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 constructor copies the TLV element octets to an internal buffer.
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use the constructor that takes a span<>")]]
|
||||
Block(const uint8_t* buf, size_t bufSize);
|
||||
|
||||
/** @brief Create a zero-length Block with the specified TLV-TYPE
|
||||
* @param type TLV-TYPE
|
||||
*/
|
||||
@@ -170,7 +162,7 @@ public: // construction, assignment
|
||||
* @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
|
||||
* @note This function does not throw upon decoding failure.
|
||||
*/
|
||||
NDN_CXX_NODISCARD static std::tuple<bool, Block>
|
||||
[[nodiscard]] static std::tuple<bool, Block>
|
||||
fromBuffer(ConstBufferPtr buffer, size_t offset = 0);
|
||||
|
||||
/** @brief Try to parse Block from a byte range
|
||||
@@ -180,21 +172,9 @@ public: // construction, assignment
|
||||
* @note This overload copies the TLV element octets to an internal buffer.
|
||||
* @note This function does not throw upon decoding failure.
|
||||
*/
|
||||
NDN_CXX_NODISCARD static std::tuple<bool, Block>
|
||||
[[nodiscard]] static std::tuple<bool, Block>
|
||||
fromBuffer(span<const uint8_t> buffer);
|
||||
|
||||
/** @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
|
||||
* @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.
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use the overload that takes a span<>")]]
|
||||
NDN_CXX_NODISCARD static std::tuple<bool, Block>
|
||||
fromBuffer(const uint8_t* buf, size_t bufSize);
|
||||
|
||||
/** @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.
|
||||
@@ -243,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
|
||||
@@ -278,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
|
||||
@@ -300,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;
|
||||
|
||||
@@ -351,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()
|
||||
*/
|
||||
@@ -366,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
|
||||
@@ -382,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
|
||||
@@ -395,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
|
||||
*
|
||||
@@ -469,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
|
||||
@@ -500,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.
|
||||
@@ -518,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-2021 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).
|
||||
*
|
||||
@@ -26,63 +26,61 @@
|
||||
|
||||
#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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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()))
|
||||
{
|
||||
@@ -200,49 +199,4 @@ Encoder::appendNonNegativeInteger(uint64_t varNumber)
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
Encoder::prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize)
|
||||
{
|
||||
size_t totalLength = prependBytes({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 += appendBytes({array, arraySize});
|
||||
|
||||
return totalLength;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
size_t
|
||||
Encoder::prependBlock(const Block& block)
|
||||
{
|
||||
if (block.hasWire()) {
|
||||
return prependBytes({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 appendBytes({block.wire(), block.size()});
|
||||
}
|
||||
else {
|
||||
return appendByteArrayBlock(block.type(), block.value(), block.value_size());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace encoding
|
||||
} // namespace ndn
|
||||
} // namespace ndn::encoding
|
||||
+11
-107
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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).
|
||||
*
|
||||
@@ -24,8 +24,9 @@
|
||||
|
||||
#include "ndn-cxx/encoding/block.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace encoding {
|
||||
#include <algorithm>
|
||||
|
||||
namespace ndn::encoding {
|
||||
|
||||
/**
|
||||
* @brief Helper class to perform TLV encoding.
|
||||
@@ -49,50 +50,6 @@ public: // common interface between Encoder and Estimator
|
||||
size_t
|
||||
appendBytes(span<const uint8_t> bytes);
|
||||
|
||||
/**
|
||||
* @brief Prepend a byte
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use prependBytes()")]]
|
||||
size_t
|
||||
prependByte(uint8_t value)
|
||||
{
|
||||
return prependBytes({value});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append a byte
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use appendBytes()")]]
|
||||
size_t
|
||||
appendByte(uint8_t value)
|
||||
{
|
||||
return appendBytes({value});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend a byte array @p array of length @p length
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use prependBytes()")]]
|
||||
size_t
|
||||
prependByteArray(const uint8_t* array, size_t length)
|
||||
{
|
||||
return prependBytes({array, length});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append a byte array @p array of length @p length
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use appendBytes()")]]
|
||||
size_t
|
||||
appendByteArray(const uint8_t* array, size_t length)
|
||||
{
|
||||
return appendBytes({array, length});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend range of bytes from the range [@p first, @p last)
|
||||
*/
|
||||
@@ -109,64 +66,32 @@ public: // common interface between Encoder and Estimator
|
||||
|
||||
/**
|
||||
* @brief Prepend @p number encoded as a VAR-NUMBER in NDN-TLV format
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
|
||||
*/
|
||||
size_t
|
||||
prependVarNumber(uint64_t number);
|
||||
|
||||
/**
|
||||
* @brief Append @p number encoded as a VAR-NUMBER in NDN-TLV format
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
|
||||
*/
|
||||
size_t
|
||||
appendVarNumber(uint64_t number);
|
||||
|
||||
/**
|
||||
* @brief Prepend @p integer encoded as a NonNegativeInteger in NDN-TLV format
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
|
||||
*/
|
||||
size_t
|
||||
prependNonNegativeInteger(uint64_t integer);
|
||||
|
||||
/**
|
||||
* @brief Append @p integer encoded as a NonNegativeInteger in NDN-TLV format
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html
|
||||
* @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
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use encoding::prependBinaryBlock()")]]
|
||||
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
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated]]
|
||||
size_t
|
||||
appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize);
|
||||
|
||||
/**
|
||||
* @brief Prepend TLV block @p block
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use encoding::prependBlock()")]]
|
||||
size_t
|
||||
prependBlock(const Block& block);
|
||||
|
||||
/**
|
||||
* @brief Append TLV block @p block
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated]]
|
||||
size_t
|
||||
appendBlock(const Block& block);
|
||||
|
||||
public: // unique interface to the Encoder
|
||||
using value_type = Buffer::value_type;
|
||||
using iterator = Buffer::iterator;
|
||||
@@ -294,26 +219,6 @@ public: // accessors
|
||||
return &*m_begin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use data()")]]
|
||||
uint8_t*
|
||||
buf() noexcept
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use data()")]]
|
||||
const uint8_t*
|
||||
buf() const noexcept
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the size of the encoded buffer
|
||||
*/
|
||||
@@ -347,7 +252,7 @@ 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);
|
||||
@@ -362,7 +267,7 @@ 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);
|
||||
@@ -372,7 +277,6 @@ Encoder::appendRange(Iterator first, Iterator last)
|
||||
return length;
|
||||
}
|
||||
|
||||
} // namespace encoding
|
||||
} // namespace ndn
|
||||
} // namespace ndn::encoding
|
||||
|
||||
#endif // NDN_CXX_ENCODING_ENCODER_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -26,8 +26,7 @@
|
||||
#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_CXX_ENCODING_ENCODING_BUFFER_HPP
|
||||
@@ -1,47 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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 {
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
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-2022 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).
|
||||
*
|
||||
@@ -24,8 +24,7 @@
|
||||
|
||||
#include "ndn-cxx/encoding/block.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace encoding {
|
||||
namespace ndn::encoding {
|
||||
|
||||
/**
|
||||
* @brief Helper class to estimate size of TLV encoding.
|
||||
@@ -55,50 +54,6 @@ public: // common interface between Encoder and Estimator
|
||||
return bytes.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend a single byte
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use prependBytes()")]]
|
||||
constexpr size_t
|
||||
prependByte(uint8_t) const noexcept
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append a single byte
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use appendBytes()")]]
|
||||
constexpr size_t
|
||||
appendByte(uint8_t) const noexcept
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend a byte array @p array of length @p length
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use prependBytes()")]]
|
||||
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
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use appendBytes()")]]
|
||||
constexpr size_t
|
||||
appendByteArray(const uint8_t*, size_t length) const noexcept
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend bytes from the range [@p first, @p last)
|
||||
*/
|
||||
@@ -106,7 +61,7 @@ public: // common interface between Encoder and Estimator
|
||||
constexpr size_t
|
||||
prependRange(Iterator first, Iterator last) const noexcept
|
||||
{
|
||||
return std::distance(first, last);
|
||||
return static_cast<size_t>(std::distance(first, last));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,7 +71,7 @@ public: // common interface between Encoder and Estimator
|
||||
constexpr size_t
|
||||
appendRange(Iterator first, Iterator last) const noexcept
|
||||
{
|
||||
return std::distance(first, last);
|
||||
return static_cast<size_t>(std::distance(first, last));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,47 +109,8 @@ public: // common interface between Encoder and Estimator
|
||||
{
|
||||
return tlv::sizeOfNonNegativeInteger(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend TLV block of type @p type and value from buffer @p array of size @p arraySize
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use encoding::prependBinaryBlock()")]]
|
||||
constexpr size_t
|
||||
prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept
|
||||
{
|
||||
return tlv::sizeOfVarNumber(type) + tlv::sizeOfVarNumber(arraySize) + arraySize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append TLV block of type @p type and value from buffer @p array of size @p arraySize
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated]]
|
||||
constexpr size_t
|
||||
appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept
|
||||
{
|
||||
return tlv::sizeOfVarNumber(type) + tlv::sizeOfVarNumber(arraySize) + arraySize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend TLV block @p block
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated("use encoding::prependBlock()")]]
|
||||
size_t
|
||||
prependBlock(const Block& block) const;
|
||||
|
||||
/**
|
||||
* @brief Append TLV block @p block
|
||||
* @deprecated
|
||||
*/
|
||||
[[deprecated]]
|
||||
size_t
|
||||
appendBlock(const Block& block) const;
|
||||
};
|
||||
|
||||
} // namespace encoding
|
||||
} // namespace ndn
|
||||
} // namespace ndn::encoding
|
||||
|
||||
#endif // NDN_CXX_ENCODING_ESTIMATOR_HPP
|
||||
@@ -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).
|
||||
*
|
||||
@@ -29,8 +29,7 @@
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
|
||||
namespace ndn {
|
||||
namespace nfd {
|
||||
namespace ndn::nfd {
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, FaceScope faceScope)
|
||||
@@ -122,8 +121,8 @@ operator>>(std::istream& is, RouteOrigin& routeOrigin)
|
||||
routeOrigin = ROUTE_ORIGIN_STATIC;
|
||||
else {
|
||||
// To reject negative numbers, we parse as a wider signed type, and compare with the range.
|
||||
static_assert(std::numeric_limits<std::underlying_type_t<RouteOrigin>>::max() <=
|
||||
std::numeric_limits<int>::max(), "");
|
||||
using RouteOriginUnderlyingType = std::underlying_type_t<RouteOrigin>;
|
||||
static_assert(std::numeric_limits<RouteOriginUnderlyingType>::max() <= std::numeric_limits<int>::max());
|
||||
|
||||
int v = -1;
|
||||
try {
|
||||
@@ -132,8 +131,8 @@ operator>>(std::istream& is, RouteOrigin& routeOrigin)
|
||||
catch (const boost::bad_lexical_cast&) {
|
||||
}
|
||||
|
||||
if (v >= std::numeric_limits<std::underlying_type_t<RouteOrigin>>::min() &&
|
||||
v <= std::numeric_limits<std::underlying_type_t<RouteOrigin>>::max()) {
|
||||
if (v >= std::numeric_limits<RouteOriginUnderlyingType>::min() &&
|
||||
v <= std::numeric_limits<RouteOriginUnderlyingType>::max()) {
|
||||
routeOrigin = static_cast<RouteOrigin>(v);
|
||||
}
|
||||
else {
|
||||
@@ -176,17 +175,13 @@ operator<<(std::ostream& os, RouteFlags routeFlags)
|
||||
return os << "none";
|
||||
}
|
||||
|
||||
static const std::map<RouteFlags, std::string> knownBits = {
|
||||
{ROUTE_FLAG_CHILD_INHERIT, "child-inherit"},
|
||||
{ROUTE_FLAG_CAPTURE, "capture"}
|
||||
static const std::map<RouteFlags, std::string_view> knownBits = {
|
||||
{ROUTE_FLAG_CHILD_INHERIT, "child-inherit"sv},
|
||||
{ROUTE_FLAG_CAPTURE, "capture"sv}
|
||||
};
|
||||
|
||||
auto join = make_ostream_joiner(os, '|');
|
||||
for (const auto& pair : knownBits) {
|
||||
RouteFlags bit = ROUTE_FLAGS_NONE;
|
||||
std::string token;
|
||||
std::tie(bit, token) = pair;
|
||||
|
||||
for (auto [bit, token] : knownBits) {
|
||||
if ((routeFlags & bit) != 0) {
|
||||
join = token;
|
||||
routeFlags = static_cast<RouteFlags>(routeFlags & ~bit);
|
||||
@@ -200,5 +195,4 @@ operator<<(std::ostream& os, RouteFlags routeFlags)
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace nfd
|
||||
} // namespace ndn
|
||||
} // namespace ndn::nfd
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -22,12 +22,13 @@
|
||||
#ifndef NDN_CXX_ENCODING_NFD_CONSTANTS_HPP
|
||||
#define NDN_CXX_ENCODING_NFD_CONSTANTS_HPP
|
||||
|
||||
#include "ndn-cxx/detail/common.hpp"
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <limits>
|
||||
|
||||
namespace ndn {
|
||||
namespace nfd {
|
||||
namespace ndn::nfd {
|
||||
|
||||
const uint64_t INVALID_FACE_ID = 0;
|
||||
inline constexpr uint64_t INVALID_FACE_ID = 0;
|
||||
|
||||
/** \ingroup management
|
||||
*/
|
||||
@@ -86,7 +87,7 @@ std::ostream&
|
||||
operator<<(std::ostream& os, FaceEventKind faceEventKind);
|
||||
|
||||
/** \ingroup management
|
||||
* \brief CS enablement flags
|
||||
* \brief CS enablement flags.
|
||||
* \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-config
|
||||
*/
|
||||
enum CsFlagBit {
|
||||
@@ -107,7 +108,7 @@ enum RouteOrigin : uint16_t {
|
||||
ROUTE_ORIGIN_STATIC = 255,
|
||||
};
|
||||
|
||||
/** \brief extract RouteOrigin from stream
|
||||
/** \brief Extract RouteOrigin from stream.
|
||||
* \post if the first token in \p contains a valid RouteOrigin as string or numeric value, it is
|
||||
* extracted into \p routeOrigin ; otherwise, \p routeOrigin is set to \p ROUTE_ORIGIN_NONE ,
|
||||
* and failbit is set on \p is
|
||||
@@ -129,7 +130,6 @@ enum RouteFlags : uint64_t {
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, RouteFlags routeFlags);
|
||||
|
||||
} // namespace nfd
|
||||
} // namespace ndn
|
||||
} // namespace ndn::nfd
|
||||
|
||||
#endif // NDN_CXX_ENCODING_NFD_CONSTANTS_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -22,15 +22,15 @@
|
||||
#ifndef NDN_CXX_ENCODING_TLV_NFD_HPP
|
||||
#define NDN_CXX_ENCODING_TLV_NFD_HPP
|
||||
|
||||
#include "ndn-cxx/encoding/tlv.hpp"
|
||||
#include "ndn-cxx/encoding/nfd-constants.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace ndn {
|
||||
namespace tlv {
|
||||
namespace nfd {
|
||||
namespace ndn::tlv::nfd {
|
||||
|
||||
// NFD Management protocol
|
||||
enum {
|
||||
/**
|
||||
* @brief TLV-TYPE numbers defined by the NFD Management protocol.
|
||||
* @sa https://redmine.named-data.net/projects/nfd/wiki/Management
|
||||
*/
|
||||
enum : uint32_t {
|
||||
// ControlParameters
|
||||
ControlParameters = 104,
|
||||
FaceId = 105,
|
||||
@@ -100,11 +100,9 @@ enum {
|
||||
|
||||
// RIB Management
|
||||
RibEntry = 128,
|
||||
Route = 129
|
||||
Route = 129,
|
||||
};
|
||||
|
||||
} // namespace nfd
|
||||
} // namespace tlv
|
||||
} // namespace ndn
|
||||
} // namespace ndn::tlv::nfd
|
||||
|
||||
#endif // NDN_CXX_ENCODING_TLV_NFD_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -22,14 +22,12 @@
|
||||
#ifndef NDN_CXX_ENCODING_TLV_SECURITY_HPP
|
||||
#define NDN_CXX_ENCODING_TLV_SECURITY_HPP
|
||||
|
||||
#include "ndn-cxx/encoding/tlv.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace ndn {
|
||||
namespace tlv {
|
||||
namespace security {
|
||||
namespace ndn::tlv::security {
|
||||
|
||||
/**
|
||||
* @brief TLV-TYPE numbers for SafeBag and related elements
|
||||
* @brief TLV-TYPE numbers for SafeBag and related elements.
|
||||
* @sa <a href="../specs/safe-bag.html">SafeBag Format</a>
|
||||
*/
|
||||
enum : uint32_t {
|
||||
@@ -37,8 +35,6 @@ enum : uint32_t {
|
||||
EncryptedKey = 129,
|
||||
};
|
||||
|
||||
} // namespace security
|
||||
} // namespace tlv
|
||||
} // namespace ndn
|
||||
} // namespace ndn::tlv::security
|
||||
|
||||
#endif // NDN_CXX_ENCODING_TLV_SECURITY_HPP
|
||||
@@ -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).
|
||||
*
|
||||
@@ -21,8 +21,9 @@
|
||||
|
||||
#include "ndn-cxx/encoding/tlv.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace tlv {
|
||||
#include <ostream>
|
||||
|
||||
namespace ndn::tlv {
|
||||
|
||||
Error::Error(const char* expectedType, uint32_t actualType)
|
||||
: Error("Expecting "s + expectedType + " element, but TLV has type " + to_string(actualType))
|
||||
@@ -41,6 +42,8 @@ operator<<(std::ostream& os, SignatureTypeValue st)
|
||||
return os << "SignatureSha256WithEcdsa";
|
||||
case SignatureHmacWithSha256:
|
||||
return os << "SignatureHmacWithSha256";
|
||||
case SignatureEd25519:
|
||||
return os << "SignatureEd25519";
|
||||
case NullSignature:
|
||||
return os << "NullSignature";
|
||||
}
|
||||
@@ -79,5 +82,55 @@ operator<<(std::ostream& os, ContentTypeValue ct)
|
||||
return os << static_cast<uint32_t>(ct) << ')';
|
||||
}
|
||||
|
||||
} // namespace tlv
|
||||
} // namespace ndn
|
||||
size_t
|
||||
writeVarNumber(std::ostream& os, uint64_t number)
|
||||
{
|
||||
if (number < 253) {
|
||||
os.put(static_cast<char>(number));
|
||||
return 1;
|
||||
}
|
||||
else if (number <= std::numeric_limits<uint16_t>::max()) {
|
||||
os.put(static_cast<char>(253));
|
||||
uint16_t value = boost::endian::native_to_big(static_cast<uint16_t>(number));
|
||||
os.write(reinterpret_cast<const char*>(&value), 2);
|
||||
return 3;
|
||||
}
|
||||
else if (number <= std::numeric_limits<uint32_t>::max()) {
|
||||
os.put(static_cast<char>(254));
|
||||
uint32_t value = boost::endian::native_to_big(static_cast<uint32_t>(number));
|
||||
os.write(reinterpret_cast<const char*>(&value), 4);
|
||||
return 5;
|
||||
}
|
||||
else {
|
||||
os.put(static_cast<char>(255));
|
||||
uint64_t value = boost::endian::native_to_big(number);
|
||||
os.write(reinterpret_cast<const char*>(&value), 8);
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
writeNonNegativeInteger(std::ostream& os, uint64_t integer)
|
||||
{
|
||||
if (integer <= std::numeric_limits<uint8_t>::max()) {
|
||||
os.put(static_cast<char>(integer));
|
||||
return 1;
|
||||
}
|
||||
else if (integer <= std::numeric_limits<uint16_t>::max()) {
|
||||
uint16_t value = boost::endian::native_to_big(static_cast<uint16_t>(integer));
|
||||
os.write(reinterpret_cast<const char*>(&value), 2);
|
||||
return 2;
|
||||
}
|
||||
else if (integer <= std::numeric_limits<uint32_t>::max()) {
|
||||
uint32_t value = boost::endian::native_to_big(static_cast<uint32_t>(integer));
|
||||
os.write(reinterpret_cast<const char*>(&value), 4);
|
||||
return 4;
|
||||
}
|
||||
else {
|
||||
uint64_t value = boost::endian::native_to_big(integer);
|
||||
os.write(reinterpret_cast<const char*>(&value), 8);
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ndn::tlv
|
||||
+107
-202
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <ostream>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
@@ -38,16 +38,17 @@ namespace ndn {
|
||||
*
|
||||
* If a packet is longer than this size, library and application MAY drop it.
|
||||
*/
|
||||
const size_t MAX_NDN_PACKET_SIZE = 8800;
|
||||
inline constexpr size_t MAX_NDN_PACKET_SIZE = 8800;
|
||||
|
||||
/**
|
||||
* @brief Namespace defining NDN Packet Format related constants and procedures
|
||||
* @brief Contains constants and low-level functions related to the NDN packet format.
|
||||
*/
|
||||
namespace tlv {
|
||||
|
||||
/** @brief represents an error in TLV encoding or decoding
|
||||
/**
|
||||
* @brief Represents an error in TLV encoding or decoding.
|
||||
*
|
||||
* Element::Error SHOULD inherit from this Error class.
|
||||
* `Element::Error` SHOULD inherit from this Error class.
|
||||
*/
|
||||
class Error : public std::runtime_error
|
||||
{
|
||||
@@ -57,26 +58,41 @@ public:
|
||||
Error(const char* expectedType, uint32_t actualType);
|
||||
};
|
||||
|
||||
/** @brief TLV-TYPE numbers defined in NDN Packet Format v0.3
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/types.html
|
||||
/**
|
||||
* @brief TLV-TYPE numbers defined in NDN Packet Format v0.3.
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/types.html
|
||||
* @sa https://redmine.named-data.net/projects/ndn-tlv/wiki/NameComponentType
|
||||
*/
|
||||
enum : uint32_t {
|
||||
Invalid = 0,
|
||||
Interest = 5,
|
||||
Data = 6,
|
||||
|
||||
Name = 7,
|
||||
GenericNameComponent = 8,
|
||||
ImplicitSha256DigestComponent = 1,
|
||||
ParametersSha256DigestComponent = 2,
|
||||
KeywordNameComponent = 32,
|
||||
SegmentNameComponent = 50,
|
||||
ByteOffsetNameComponent = 52,
|
||||
VersionNameComponent = 54,
|
||||
TimestampNameComponent = 56,
|
||||
SequenceNumNameComponent = 58,
|
||||
|
||||
CanBePrefix = 33,
|
||||
MustBeFresh = 18,
|
||||
ForwardingHint = 30,
|
||||
Nonce = 10,
|
||||
InterestLifetime = 12,
|
||||
HopLimit = 34,
|
||||
ServiceClass = 129,
|
||||
DownstreamRate = 130,
|
||||
TargetRate = 131,
|
||||
Dsz = 132,
|
||||
ApplicationParameters = 36,
|
||||
InterestSignatureInfo = 44,
|
||||
InterestSignatureValue = 46,
|
||||
|
||||
MetaInfo = 20,
|
||||
Content = 21,
|
||||
SignatureInfo = 22,
|
||||
@@ -84,14 +100,21 @@ enum : uint32_t {
|
||||
ContentType = 24,
|
||||
FreshnessPeriod = 25,
|
||||
FinalBlockId = 26,
|
||||
|
||||
SignatureType = 27,
|
||||
KeyLocator = 28,
|
||||
KeyDigest = 29,
|
||||
SignatureNonce = 38,
|
||||
SignatureTime = 40,
|
||||
SignatureSeqNum = 42,
|
||||
LinkDelegation = 31,
|
||||
LinkPreference = 30,
|
||||
|
||||
ValidityPeriod = 253,
|
||||
NotBefore = 254,
|
||||
NotAfter = 255,
|
||||
AdditionalDescription = 258,
|
||||
DescriptionEntry = 512,
|
||||
DescriptionKey = 513,
|
||||
DescriptionValue = 514,
|
||||
|
||||
NameComponentMin = 1,
|
||||
NameComponentMax = 65535,
|
||||
@@ -100,62 +123,27 @@ enum : uint32_t {
|
||||
AppPrivateBlock2 = 32768,
|
||||
};
|
||||
|
||||
/** @brief TLV-TYPE numbers defined in NDN Packet Format v0.2 but not in v0.3
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.2.1/types.html
|
||||
*/
|
||||
enum : uint32_t {
|
||||
Selectors = 9,
|
||||
MinSuffixComponents = 13,
|
||||
MaxSuffixComponents = 14,
|
||||
PublisherPublicKeyLocator = 15,
|
||||
Exclude = 16,
|
||||
ChildSelector = 17,
|
||||
Any = 19,
|
||||
};
|
||||
|
||||
/** @brief TLV-TYPE numbers for typed name components.
|
||||
* @sa https://redmine.named-data.net/projects/ndn-tlv/wiki/NameComponentType
|
||||
*/
|
||||
enum : uint32_t {
|
||||
KeywordNameComponent = 32,
|
||||
SegmentNameComponent = 50,
|
||||
ByteOffsetNameComponent = 52,
|
||||
VersionNameComponent = 54,
|
||||
TimestampNameComponent = 56,
|
||||
SequenceNumNameComponent = 58,
|
||||
};
|
||||
|
||||
/** @brief SignatureType values
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/current/signature.html
|
||||
* @sa https://redmine.named-data.net/projects/ndn-tlv/wiki/SignatureType
|
||||
/**
|
||||
* @brief SignatureType values.
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/signature.html#signaturetype
|
||||
* @sa https://redmine.named-data.net/projects/ndn-tlv/wiki/SignatureType
|
||||
*/
|
||||
enum SignatureTypeValue : uint16_t {
|
||||
DigestSha256 = 0,
|
||||
SignatureSha256WithRsa = 1,
|
||||
SignatureSha256WithEcdsa = 3,
|
||||
SignatureHmacWithSha256 = 4,
|
||||
SignatureEd25519 = 5,
|
||||
NullSignature = 200,
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, SignatureTypeValue st);
|
||||
|
||||
/** @brief TLV-TYPE numbers for SignatureInfo extensions
|
||||
* @sa <a href="../specs/certificate.html">NDN Certificate Format</a>
|
||||
*/
|
||||
enum : uint32_t {
|
||||
ValidityPeriod = 253,
|
||||
NotBefore = 254,
|
||||
NotAfter = 255,
|
||||
|
||||
AdditionalDescription = 258,
|
||||
DescriptionEntry = 512,
|
||||
DescriptionKey = 513,
|
||||
DescriptionValue = 514
|
||||
};
|
||||
|
||||
/** @brief ContentType values
|
||||
* @sa https://redmine.named-data.net/projects/ndn-tlv/wiki/ContentType
|
||||
/**
|
||||
* @brief ContentType values.
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/data.html#contenttype
|
||||
* @sa https://redmine.named-data.net/projects/ndn-tlv/wiki/ContentType
|
||||
*/
|
||||
enum ContentTypeValue : uint32_t {
|
||||
ContentType_Blob = 0, ///< payload
|
||||
@@ -172,10 +160,10 @@ operator<<(std::ostream& os, ContentTypeValue ct);
|
||||
|
||||
/**
|
||||
* @brief Determine whether a TLV-TYPE is "critical" for evolvability purpose.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/tlv.html#considerations-for-evolvability-of-tlv-based-encoding
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html#considerations-for-evolvability-of-tlv-based-encoding
|
||||
*/
|
||||
constexpr bool
|
||||
isCriticalType(uint32_t type)
|
||||
isCriticalType(uint32_t type) noexcept
|
||||
{
|
||||
return type <= 31 || (type & 0x01);
|
||||
}
|
||||
@@ -184,73 +172,73 @@ isCriticalType(uint32_t type)
|
||||
* @brief Read VAR-NUMBER in NDN-TLV encoding.
|
||||
* @tparam Iterator an iterator or pointer that dereferences to uint8_t or compatible type
|
||||
*
|
||||
* @param [inout] begin Begin of the buffer, will be incremented to point to the first byte after
|
||||
* @param[in,out] begin Begin of the buffer, will be incremented to point to the first byte after
|
||||
* the read VAR-NUMBER
|
||||
* @param [in] end End of the buffer
|
||||
* @param [out] number Read VAR-NUMBER
|
||||
* @param[in] end End of the buffer
|
||||
* @param[out] number Read VAR-NUMBER
|
||||
*
|
||||
* @return true if number was successfully read from input, false otherwise
|
||||
*/
|
||||
template<typename Iterator>
|
||||
NDN_CXX_NODISCARD bool
|
||||
[[nodiscard]] constexpr bool
|
||||
readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Read TLV-TYPE.
|
||||
* @tparam Iterator an iterator or pointer that dereferences to uint8_t or compatible type
|
||||
*
|
||||
* @param [inout] begin Begin of the buffer, will be incremented to point to the first byte after
|
||||
* @param[in,out] begin Begin of the buffer, will be incremented to point to the first byte after
|
||||
* the read TLV-TYPE
|
||||
* @param [in] end End of the buffer
|
||||
* @param [out] type Read TLV-TYPE
|
||||
* @param[in] end End of the buffer
|
||||
* @param[out] type Read TLV-TYPE
|
||||
*
|
||||
* @return true if TLV-TYPE was successfully read from input, false otherwise
|
||||
* @note This function is largely equivalent to readVarNumber(), except that it returns false if
|
||||
* the TLV-TYPE is zero or larger than 2^32-1 (maximum allowed by the packet format).
|
||||
*/
|
||||
template<typename Iterator>
|
||||
NDN_CXX_NODISCARD bool
|
||||
[[nodiscard]] constexpr bool
|
||||
readType(Iterator& begin, Iterator end, uint32_t& type) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Read VAR-NUMBER in NDN-TLV encoding.
|
||||
* @tparam Iterator an iterator or pointer that dereferences to uint8_t or compatible type
|
||||
*
|
||||
* @param [inout] begin Begin of the buffer, will be incremented to point to the first byte after
|
||||
* @param[in,out] begin Begin of the buffer, will be incremented to point to the first byte after
|
||||
* the read VAR-NUMBER
|
||||
* @param [in] end End of the buffer
|
||||
* @param[in] end End of the buffer
|
||||
*
|
||||
* @throw tlv::Error VAR-NUMBER cannot be read
|
||||
*/
|
||||
template<typename Iterator>
|
||||
uint64_t
|
||||
constexpr uint64_t
|
||||
readVarNumber(Iterator& begin, Iterator end);
|
||||
|
||||
/**
|
||||
* @brief Read TLV-TYPE.
|
||||
* @tparam Iterator an iterator or pointer that dereferences to uint8_t or compatible type
|
||||
*
|
||||
* @param [inout] begin Begin of the buffer, will be incremented to point to the first byte after
|
||||
* @param[in,out] begin Begin of the buffer, will be incremented to point to the first byte after
|
||||
* the read TLV-TYPE
|
||||
* @param [in] end End of the buffer
|
||||
* @param[in] end End of the buffer
|
||||
*
|
||||
* @throw tlv::Error TLV-TYPE cannot be read
|
||||
* @note This function is largely equivalent to readVarNumber(), except that it throws if
|
||||
* the TLV-TYPE is zero or larger than 2^32-1 (maximum allowed by the packet format).
|
||||
*/
|
||||
template<typename Iterator>
|
||||
uint32_t
|
||||
constexpr uint32_t
|
||||
readType(Iterator& begin, Iterator end);
|
||||
|
||||
/**
|
||||
* @brief Get the number of bytes necessary to hold the value of @p number encoded as VAR-NUMBER.
|
||||
*/
|
||||
constexpr size_t
|
||||
[[nodiscard]] constexpr size_t
|
||||
sizeOfVarNumber(uint64_t number) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Write VAR-NUMBER to the specified stream.
|
||||
* @return length of written VAR-NUMBER
|
||||
* @return Length of written VAR-NUMBER.
|
||||
*/
|
||||
size_t
|
||||
writeVarNumber(std::ostream& os, uint64_t number);
|
||||
@@ -259,75 +247,62 @@ writeVarNumber(std::ostream& os, uint64_t number);
|
||||
* @brief Read a NonNegativeInteger in NDN-TLV encoding.
|
||||
* @tparam Iterator an iterator or pointer that dereferences to uint8_t or compatible type
|
||||
*
|
||||
* @param [in] size size of the NonNegativeInteger
|
||||
* @param [inout] begin Begin of the buffer, will be incremented to point to the first byte after
|
||||
* @param[in] size size of the NonNegativeInteger
|
||||
* @param[in,out] begin Begin of the buffer, will be incremented to point to the first byte after
|
||||
* the read NonNegativeInteger
|
||||
* @param [in] end End of the buffer
|
||||
* @param[in] end End of the buffer
|
||||
*
|
||||
* @throw tlv::Error number cannot be read
|
||||
* @note How many bytes to read is directly controlled by \p size, which can be either 1, 2, 4, or 8.
|
||||
* If \p size differs from `std::distance(begin, end)`, tlv::Error exception will be thrown.
|
||||
*/
|
||||
template<typename Iterator>
|
||||
uint64_t
|
||||
constexpr uint64_t
|
||||
readNonNegativeInteger(size_t size, Iterator& begin, Iterator end);
|
||||
|
||||
/**
|
||||
* @brief Get the number of bytes necessary to hold the value of @p integer encoded as NonNegativeInteger.
|
||||
*/
|
||||
constexpr size_t
|
||||
[[nodiscard]] constexpr size_t
|
||||
sizeOfNonNegativeInteger(uint64_t integer) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Write a NonNegativeInteger to the specified stream.
|
||||
* @return length of written NonNegativeInteger
|
||||
* @return Length of written NonNegativeInteger.
|
||||
*/
|
||||
size_t
|
||||
writeNonNegativeInteger(std::ostream& os, uint64_t integer);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Inline definitions
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail {
|
||||
|
||||
/** @brief Function object to read a number from InputIterator
|
||||
/**
|
||||
* @brief Determine whether to select the readNumber() implementation for ContiguousIterator.
|
||||
*
|
||||
* This is not a full ContiguousIterator detection implementation. It returns true for
|
||||
* the most common ContiguousIterator types used with TLV decoding function templates.
|
||||
*/
|
||||
template<typename Iterator>
|
||||
class ReadNumberSlow
|
||||
{
|
||||
public:
|
||||
constexpr bool
|
||||
operator()(size_t size, Iterator& begin, Iterator end, uint64_t& number) const noexcept
|
||||
{
|
||||
number = 0;
|
||||
size_t count = 0;
|
||||
for (; begin != end && count < size; ++begin, ++count) {
|
||||
number = (number << 8) | *begin;
|
||||
}
|
||||
return count == size;
|
||||
}
|
||||
};
|
||||
template<typename Iterator,
|
||||
typename DecayedIterator = std::decay_t<Iterator>,
|
||||
typename ValueType = typename std::iterator_traits<DecayedIterator>::value_type>
|
||||
inline constexpr bool IsContiguousIterator =
|
||||
(std::is_convertible_v<DecayedIterator, const ValueType*> ||
|
||||
std::is_convertible_v<DecayedIterator, typename std::basic_string<ValueType>::const_iterator> ||
|
||||
std::is_convertible_v<DecayedIterator, typename std::vector<ValueType>::const_iterator>) &&
|
||||
sizeof(ValueType) == 1 && !std::is_same_v<ValueType, bool>;
|
||||
|
||||
/** @brief Function object to read a number from ContiguousIterator
|
||||
*/
|
||||
template<typename Iterator>
|
||||
class ReadNumberFast
|
||||
constexpr bool
|
||||
readNumber(size_t size, Iterator& begin, Iterator end, uint64_t& number) noexcept
|
||||
{
|
||||
public:
|
||||
constexpr bool
|
||||
operator()(size_t size, Iterator& begin, Iterator end, uint64_t& number) const noexcept
|
||||
{
|
||||
if constexpr (IsContiguousIterator<Iterator>) {
|
||||
// fast path
|
||||
if (begin + size > end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (size) {
|
||||
case 1: {
|
||||
number = *begin;
|
||||
@@ -360,36 +335,21 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief Determine whether to select ReadNumber implementation for ContiguousIterator
|
||||
*
|
||||
* This is not a full ContiguousIterator detection implementation. It returns true for the most
|
||||
* common ContiguousIterator types used with TLV decoding function templates.
|
||||
*/
|
||||
template<typename Iterator,
|
||||
typename DecayedIterator = std::decay_t<Iterator>,
|
||||
typename ValueType = typename std::iterator_traits<DecayedIterator>::value_type>
|
||||
constexpr bool
|
||||
shouldSelectContiguousReadNumber()
|
||||
{
|
||||
return (std::is_convertible<DecayedIterator, const ValueType*>::value ||
|
||||
std::is_convertible<DecayedIterator, typename std::basic_string<ValueType>::const_iterator>::value ||
|
||||
std::is_convertible<DecayedIterator, typename std::vector<ValueType>::const_iterator>::value) &&
|
||||
sizeof(ValueType) == 1 &&
|
||||
!std::is_same<ValueType, bool>::value;
|
||||
else {
|
||||
// slow path
|
||||
number = 0;
|
||||
size_t count = 0;
|
||||
for (; begin != end && count < size; ++begin, ++count) {
|
||||
number = (number << 8) | *begin;
|
||||
}
|
||||
return count == size;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
class ReadNumber : public std::conditional_t<shouldSelectContiguousReadNumber<Iterator>(),
|
||||
ReadNumberFast<Iterator>, ReadNumberSlow<Iterator>>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename Iterator>
|
||||
bool
|
||||
constexpr bool
|
||||
readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept
|
||||
{
|
||||
if (begin == end)
|
||||
@@ -402,13 +362,12 @@ readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t size = firstOctet == 253 ? 2 :
|
||||
firstOctet == 254 ? 4 : 8;
|
||||
return detail::ReadNumber<Iterator>()(size, begin, end, number);
|
||||
size_t len = 1U << (firstOctet & 0b11);
|
||||
return detail::readNumber(len, begin, end, number);
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
bool
|
||||
constexpr bool
|
||||
readType(Iterator& begin, Iterator end, uint32_t& type) noexcept
|
||||
{
|
||||
uint64_t number = 0;
|
||||
@@ -422,24 +381,20 @@ readType(Iterator& begin, Iterator end, uint32_t& type) noexcept
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
uint64_t
|
||||
constexpr uint64_t
|
||||
readVarNumber(Iterator& begin, Iterator end)
|
||||
{
|
||||
if (begin == end) {
|
||||
NDN_THROW(Error("Empty buffer during TLV parsing"));
|
||||
}
|
||||
|
||||
uint64_t value = 0;
|
||||
bool isOk = readVarNumber(begin, end, value);
|
||||
uint64_t number = 0;
|
||||
bool isOk = readVarNumber(begin, end, number);
|
||||
if (!isOk) {
|
||||
NDN_THROW(Error("Insufficient data during TLV parsing"));
|
||||
}
|
||||
|
||||
return value;
|
||||
return number;
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
uint32_t
|
||||
constexpr uint32_t
|
||||
readType(Iterator& begin, Iterator end)
|
||||
{
|
||||
uint64_t type = readVarNumber(begin, end);
|
||||
@@ -458,43 +413,16 @@ sizeOfVarNumber(uint64_t number) noexcept
|
||||
number <= std::numeric_limits<uint32_t>::max() ? 5 : 9;
|
||||
}
|
||||
|
||||
inline size_t
|
||||
writeVarNumber(std::ostream& os, uint64_t number)
|
||||
{
|
||||
if (number < 253) {
|
||||
os.put(static_cast<char>(number));
|
||||
return 1;
|
||||
}
|
||||
else if (number <= std::numeric_limits<uint16_t>::max()) {
|
||||
os.put(static_cast<char>(253));
|
||||
uint16_t value = boost::endian::native_to_big(static_cast<uint16_t>(number));
|
||||
os.write(reinterpret_cast<const char*>(&value), 2);
|
||||
return 3;
|
||||
}
|
||||
else if (number <= std::numeric_limits<uint32_t>::max()) {
|
||||
os.put(static_cast<char>(254));
|
||||
uint32_t value = boost::endian::native_to_big(static_cast<uint32_t>(number));
|
||||
os.write(reinterpret_cast<const char*>(&value), 4);
|
||||
return 5;
|
||||
}
|
||||
else {
|
||||
os.put(static_cast<char>(255));
|
||||
uint64_t value = boost::endian::native_to_big(number);
|
||||
os.write(reinterpret_cast<const char*>(&value), 8);
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
uint64_t
|
||||
readNonNegativeInteger(size_t size, Iterator& begin, Iterator end)
|
||||
constexpr uint64_t
|
||||
readNonNegativeInteger(size_t len, Iterator& begin, Iterator end)
|
||||
{
|
||||
if (size != 1 && size != 2 && size != 4 && size != 8) {
|
||||
NDN_THROW(Error("Invalid length " + to_string(size) + " for NonNegativeInteger"));
|
||||
if (len != 1 && len != 2 && len != 4 && len != 8) {
|
||||
NDN_THROW(Error("Invalid NonNegativeInteger length " + to_string(len)));
|
||||
}
|
||||
|
||||
uint64_t number = 0;
|
||||
bool isOk = detail::ReadNumber<Iterator>()(size, begin, end, number);
|
||||
bool isOk = detail::readNumber(len, begin, end, number);
|
||||
if (!isOk) {
|
||||
NDN_THROW(Error("Insufficient data during NonNegativeInteger parsing"));
|
||||
}
|
||||
@@ -510,31 +438,8 @@ sizeOfNonNegativeInteger(uint64_t integer) noexcept
|
||||
integer <= std::numeric_limits<uint32_t>::max() ? 4 : 8;
|
||||
}
|
||||
|
||||
inline size_t
|
||||
writeNonNegativeInteger(std::ostream& os, uint64_t integer)
|
||||
{
|
||||
if (integer <= std::numeric_limits<uint8_t>::max()) {
|
||||
os.put(static_cast<char>(integer));
|
||||
return 1;
|
||||
}
|
||||
else if (integer <= std::numeric_limits<uint16_t>::max()) {
|
||||
uint16_t value = boost::endian::native_to_big(static_cast<uint16_t>(integer));
|
||||
os.write(reinterpret_cast<const char*>(&value), 2);
|
||||
return 2;
|
||||
}
|
||||
else if (integer <= std::numeric_limits<uint32_t>::max()) {
|
||||
uint32_t value = boost::endian::native_to_big(static_cast<uint32_t>(integer));
|
||||
os.write(reinterpret_cast<const char*>(&value), 4);
|
||||
return 4;
|
||||
}
|
||||
else {
|
||||
uint64_t value = boost::endian::native_to_big(integer);
|
||||
os.write(reinterpret_cast<const char*>(&value), 8);
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tlv
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_CXX_ENCODING_TLV_HPP
|
||||
|
||||
+77
-81
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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,36 +20,24 @@
|
||||
*/
|
||||
|
||||
#include "ndn-cxx/face.hpp"
|
||||
|
||||
#include "ndn-cxx/encoding/tlv.hpp"
|
||||
#include "ndn-cxx/impl/face-impl.hpp"
|
||||
#include "ndn-cxx/net/face-uri.hpp"
|
||||
#include "ndn-cxx/security/signing-helpers.hpp"
|
||||
#include "ndn-cxx/transport/tcp-transport.hpp"
|
||||
#include "ndn-cxx/transport/unix-transport.hpp"
|
||||
#include "ndn-cxx/util/config-file.hpp"
|
||||
#include "ndn-cxx/util/scope.hpp"
|
||||
#include "ndn-cxx/util/time.hpp"
|
||||
|
||||
// NDN_LOG_INIT(ndn.Face) is declared in face-impl.hpp
|
||||
|
||||
// A callback scheduled through io.post and io.dispatch may be invoked after the face is destructed.
|
||||
// To prevent this situation, use these macros to capture Face::m_impl as weak_ptr and skip callback
|
||||
// execution if the face has been destructed.
|
||||
#define IO_CAPTURE_WEAK_IMPL(OP) \
|
||||
{ \
|
||||
weak_ptr<Impl> implWeak(m_impl); \
|
||||
m_ioService.OP([=] { \
|
||||
auto impl = implWeak.lock(); \
|
||||
if (impl != nullptr) {
|
||||
#define IO_CAPTURE_WEAK_IMPL_END \
|
||||
} \
|
||||
}); \
|
||||
}
|
||||
|
||||
namespace ndn {
|
||||
|
||||
// NDN_LOG_INIT(ndn.Face) is declared in face-impl.hpp
|
||||
|
||||
Face::OversizedPacketError::OversizedPacketError(char pktType, const Name& name, size_t wireSize)
|
||||
: Error((pktType == 'I' ? "Interest " : pktType == 'D' ? "Data " : "Nack ") +
|
||||
name.toUri() + " encodes into " + to_string(wireSize) + " octets, "
|
||||
"exceeding the implementation limit of " + to_string(MAX_NDN_PACKET_SIZE) + " octets")
|
||||
name.toUri() + " encodes into " + std::to_string(wireSize) + " octets, "
|
||||
"exceeding the implementation limit of " + std::to_string(MAX_NDN_PACKET_SIZE) + " octets")
|
||||
, pktType(pktType)
|
||||
, name(name)
|
||||
, wireSize(wireSize)
|
||||
@@ -57,50 +45,50 @@ Face::OversizedPacketError::OversizedPacketError(char pktType, const Name& name,
|
||||
}
|
||||
|
||||
Face::Face(shared_ptr<Transport> transport)
|
||||
: m_internalIoService(make_unique<boost::asio::io_service>())
|
||||
, m_ioService(*m_internalIoService)
|
||||
: m_internalIoCtx(make_unique<boost::asio::io_context>())
|
||||
, m_ioCtx(*m_internalIoCtx)
|
||||
, m_internalKeyChain(make_unique<KeyChain>())
|
||||
{
|
||||
construct(std::move(transport), *m_internalKeyChain);
|
||||
}
|
||||
|
||||
Face::Face(boost::asio::io_service& ioService)
|
||||
: m_ioService(ioService)
|
||||
Face::Face(boost::asio::io_context& ioCtx)
|
||||
: m_ioCtx(ioCtx)
|
||||
, m_internalKeyChain(make_unique<KeyChain>())
|
||||
{
|
||||
construct(nullptr, *m_internalKeyChain);
|
||||
}
|
||||
|
||||
Face::Face(const std::string& host, const std::string& port)
|
||||
: m_internalIoService(make_unique<boost::asio::io_service>())
|
||||
, m_ioService(*m_internalIoService)
|
||||
: m_internalIoCtx(make_unique<boost::asio::io_context>())
|
||||
, m_ioCtx(*m_internalIoCtx)
|
||||
, m_internalKeyChain(make_unique<KeyChain>())
|
||||
{
|
||||
construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
|
||||
}
|
||||
|
||||
Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
|
||||
: m_internalIoService(make_unique<boost::asio::io_service>())
|
||||
, m_ioService(*m_internalIoService)
|
||||
: m_internalIoCtx(make_unique<boost::asio::io_context>())
|
||||
, m_ioCtx(*m_internalIoCtx)
|
||||
{
|
||||
construct(std::move(transport), keyChain);
|
||||
}
|
||||
|
||||
Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService)
|
||||
: m_ioService(ioService)
|
||||
Face::Face(shared_ptr<Transport> transport, boost::asio::io_context& ioCtx)
|
||||
: m_ioCtx(ioCtx)
|
||||
, m_internalKeyChain(make_unique<KeyChain>())
|
||||
{
|
||||
construct(std::move(transport), *m_internalKeyChain);
|
||||
}
|
||||
|
||||
Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
|
||||
: m_ioService(ioService)
|
||||
Face::Face(shared_ptr<Transport> transport, boost::asio::io_context& ioCtx, KeyChain& keyChain)
|
||||
: m_ioCtx(ioCtx)
|
||||
{
|
||||
construct(std::move(transport), keyChain);
|
||||
}
|
||||
|
||||
shared_ptr<Transport>
|
||||
Face::makeDefaultTransport()
|
||||
static shared_ptr<Transport>
|
||||
makeDefaultTransport()
|
||||
{
|
||||
std::string transportUri;
|
||||
|
||||
@@ -118,11 +106,8 @@ Face::makeDefaultTransport()
|
||||
return UnixTransport::create("");
|
||||
}
|
||||
|
||||
std::string protocol;
|
||||
try {
|
||||
FaceUri uri(transportUri);
|
||||
protocol = uri.getScheme();
|
||||
|
||||
std::string protocol = FaceUri(transportUri).getScheme();
|
||||
if (protocol == "unix") {
|
||||
return UnixTransport::create(transportUri);
|
||||
}
|
||||
@@ -153,9 +138,11 @@ Face::construct(shared_ptr<Transport> transport, KeyChain& keyChain)
|
||||
}
|
||||
m_transport = std::move(transport);
|
||||
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->ensureConnected(false);
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
boost::asio::post(m_ioCtx, [w = m_impl->weak_from_this()] {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->ensureConnected(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Face::~Face() = default;
|
||||
@@ -167,13 +154,14 @@ Face::expressInterest(const Interest& interest,
|
||||
const TimeoutCallback& afterTimeout)
|
||||
{
|
||||
auto id = m_impl->m_pendingInterestTable.allocateId();
|
||||
|
||||
auto interest2 = make_shared<Interest>(interest);
|
||||
interest2->getNonce();
|
||||
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->expressInterest(id, interest2, afterSatisfied, afterNacked, afterTimeout);
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
boost::asio::post(m_ioCtx, [=, w = m_impl->weak_from_this()] {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->expressInterest(id, interest2, afterSatisfied, afterNacked, afterTimeout);
|
||||
}
|
||||
});
|
||||
|
||||
return PendingInterestHandle(m_impl, id);
|
||||
}
|
||||
@@ -181,9 +169,11 @@ Face::expressInterest(const Interest& interest,
|
||||
void
|
||||
Face::removeAllPendingInterests()
|
||||
{
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->removeAllPendingInterests();
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
boost::asio::post(m_ioCtx, [w = m_impl->weak_from_this()] {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->removeAllPendingInterests();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -193,19 +183,23 @@ Face::getNPendingInterests() const
|
||||
}
|
||||
|
||||
void
|
||||
Face::put(Data data)
|
||||
Face::put(const Data& data)
|
||||
{
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->putData(data);
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
boost::asio::post(m_ioCtx, [data, w = m_impl->weak_from_this()] {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->putData(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
Face::put(lp::Nack nack)
|
||||
Face::put(const lp::Nack& nack)
|
||||
{
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->putNack(nack);
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
boost::asio::post(m_ioCtx, [nack, w = m_impl->weak_from_this()] {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->putNack(nack);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RegisteredPrefixHandle
|
||||
@@ -235,9 +229,11 @@ Face::setInterestFilter(const InterestFilter& filter, const InterestCallback& on
|
||||
{
|
||||
auto id = m_impl->m_interestFilterTable.allocateId();
|
||||
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->setInterestFilter(id, filter, onInterest);
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
boost::asio::post(m_ioCtx, [=, w = m_impl->weak_from_this()] {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->setInterestFilter(id, filter, onInterest);
|
||||
}
|
||||
});
|
||||
|
||||
return InterestFilterHandle(m_impl, id);
|
||||
}
|
||||
@@ -252,53 +248,56 @@ Face::registerPrefix(const Name& prefix,
|
||||
nfd::CommandOptions options;
|
||||
options.setSigningInfo(signingInfo);
|
||||
|
||||
auto id = m_impl->registerPrefix(prefix, onSuccess, onFailure, flags, options, nullopt, nullptr);
|
||||
auto id = m_impl->registerPrefix(prefix, onSuccess, onFailure, flags, options, std::nullopt, nullptr);
|
||||
return RegisteredPrefixHandle(m_impl, id);
|
||||
}
|
||||
|
||||
void
|
||||
Face::doProcessEvents(time::milliseconds timeout, bool keepThread)
|
||||
Face::doProcessEvents(time::milliseconds timeout, bool keepRunning)
|
||||
{
|
||||
if (m_ioService.stopped()) {
|
||||
m_ioService.reset(); // ensure that run()/poll() will do some work
|
||||
if (m_ioCtx.stopped()) {
|
||||
m_ioCtx.restart(); // ensure that run()/poll() will do some work
|
||||
}
|
||||
|
||||
auto onThrow = make_scope_fail([this] { m_impl->shutdown(); });
|
||||
|
||||
if (timeout < 0_ms) {
|
||||
// do not block if timeout is negative, but process pending events
|
||||
m_ioService.poll();
|
||||
m_ioCtx.poll();
|
||||
return;
|
||||
}
|
||||
|
||||
if (timeout > 0_ms) {
|
||||
// TODO: consider using m_ioCtx.run_for(timeout) in this case
|
||||
m_impl->m_processEventsTimeoutEvent = m_impl->m_scheduler.schedule(timeout,
|
||||
[&io = m_ioService, &work = m_impl->m_ioServiceWork] {
|
||||
[&io = m_ioCtx, &work = m_impl->m_workGuard] {
|
||||
io.stop();
|
||||
work.reset();
|
||||
});
|
||||
}
|
||||
|
||||
if (keepThread) {
|
||||
// work will ensure that m_ioService is running until work object exists
|
||||
m_impl->m_ioServiceWork = make_unique<boost::asio::io_service::work>(m_ioService);
|
||||
if (keepRunning) {
|
||||
// m_workGuard ensures that m_ioCtx keeps running even when it runs out of work (events)
|
||||
m_impl->m_workGuard = make_unique<Impl::IoContextWorkGuard>(m_ioCtx.get_executor());
|
||||
}
|
||||
|
||||
m_ioService.run();
|
||||
m_ioCtx.run();
|
||||
}
|
||||
|
||||
void
|
||||
Face::shutdown()
|
||||
{
|
||||
IO_CAPTURE_WEAK_IMPL(post) {
|
||||
impl->shutdown();
|
||||
if (m_transport->isConnected())
|
||||
m_transport->close();
|
||||
} IO_CAPTURE_WEAK_IMPL_END
|
||||
boost::asio::post(m_ioCtx, [this, w = m_impl->weak_from_this()] {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->shutdown();
|
||||
if (m_transport->getState() != Transport::State::CLOSED)
|
||||
m_transport->close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief extract local fields from NDNLPv2 packet and tag onto a network layer packet
|
||||
* @brief Extract local fields from NDNLPv2 packet and tag onto a network layer packet.
|
||||
*/
|
||||
template<typename NetPkt>
|
||||
static void
|
||||
@@ -345,8 +344,7 @@ Face::onReceiveElement(const Block& blockFromDaemon)
|
||||
|
||||
PendingInterestHandle::PendingInterestHandle(weak_ptr<Face::Impl> weakImpl, detail::RecordId id)
|
||||
: CancelHandle([w = std::move(weakImpl), id] {
|
||||
auto impl = w.lock();
|
||||
if (impl != nullptr) {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->asyncRemovePendingInterest(id);
|
||||
}
|
||||
})
|
||||
@@ -382,8 +380,7 @@ RegisteredPrefixHandle::unregister(const weak_ptr<Face::Impl>& weakImpl, detail:
|
||||
const UnregisterPrefixSuccessCallback& onSuccess,
|
||||
const UnregisterPrefixFailureCallback& onFailure)
|
||||
{
|
||||
auto impl = weakImpl.lock();
|
||||
if (impl != nullptr) {
|
||||
if (auto impl = weakImpl.lock(); impl != nullptr) {
|
||||
impl->asyncUnregisterPrefix(id, onSuccess, onFailure);
|
||||
}
|
||||
else if (onFailure) {
|
||||
@@ -393,8 +390,7 @@ RegisteredPrefixHandle::unregister(const weak_ptr<Face::Impl>& weakImpl, detail:
|
||||
|
||||
InterestFilterHandle::InterestFilterHandle(weak_ptr<Face::Impl> weakImpl, detail::RecordId id)
|
||||
: CancelHandle([w = std::move(weakImpl), id] {
|
||||
auto impl = w.lock();
|
||||
if (impl != nullptr) {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->asyncUnsetInterestFilter(id);
|
||||
}
|
||||
})
|
||||
|
||||
+87
-88
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -47,42 +47,42 @@ using RecordId = uint64_t;
|
||||
/**
|
||||
* @brief Callback invoked when an expressed Interest is satisfied by a Data packet
|
||||
*/
|
||||
typedef function<void(const Interest&, const Data&)> DataCallback;
|
||||
using DataCallback = std::function<void(const Interest&, const Data&)>;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when a Nack is received in response to an expressed Interest
|
||||
*/
|
||||
typedef function<void(const Interest&, const lp::Nack&)> NackCallback;
|
||||
using NackCallback = std::function<void(const Interest&, const lp::Nack&)>;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when an expressed Interest times out
|
||||
*/
|
||||
typedef function<void(const Interest&)> TimeoutCallback;
|
||||
using TimeoutCallback = std::function<void(const Interest&)>;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when an incoming Interest matches the specified InterestFilter
|
||||
*/
|
||||
typedef function<void(const InterestFilter&, const Interest&)> InterestCallback;
|
||||
using InterestCallback = std::function<void(const InterestFilter&, const Interest&)>;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when registerPrefix or setInterestFilter command succeeds
|
||||
*/
|
||||
typedef function<void(const Name&)> RegisterPrefixSuccessCallback;
|
||||
using RegisterPrefixSuccessCallback = std::function<void(const Name&)>;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when registerPrefix or setInterestFilter command fails
|
||||
*/
|
||||
typedef function<void(const Name&, const std::string&)> RegisterPrefixFailureCallback;
|
||||
using RegisterPrefixFailureCallback = std::function<void(const Name&, const std::string&)>;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when unregistering a prefix succeeds
|
||||
*/
|
||||
typedef function<void()> UnregisterPrefixSuccessCallback;
|
||||
using UnregisterPrefixSuccessCallback = std::function<void()>;
|
||||
|
||||
/**
|
||||
* @brief Callback invoked when unregistering a prefix fails
|
||||
*/
|
||||
typedef function<void(const std::string&)> UnregisterPrefixFailureCallback;
|
||||
using UnregisterPrefixFailureCallback = std::function<void(const std::string&)>;
|
||||
|
||||
/**
|
||||
* @brief Provide a communication channel with local or remote NDN forwarder
|
||||
@@ -118,7 +118,7 @@ public:
|
||||
|
||||
public: // constructors
|
||||
/**
|
||||
* @brief Create Face using given transport (or default transport if omitted)
|
||||
* @brief Create Face using the given Transport (or default transport if omitted).
|
||||
* @param transport the transport for lower layer communication. If nullptr,
|
||||
* a default transport will be used. The default transport is
|
||||
* determined from a FaceUri in NDN_CLIENT_TRANSPORT environ,
|
||||
@@ -132,38 +132,36 @@ public: // constructors
|
||||
Face(shared_ptr<Transport> transport = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Create Face using default transport and given io_service
|
||||
* @brief Create Face using default transport and given io_context.
|
||||
*
|
||||
* Usage examples:
|
||||
*
|
||||
* @code
|
||||
* Face face1;
|
||||
* Face face2(face1.getIoService());
|
||||
* Face face2(face1.getIoContext());
|
||||
*
|
||||
* // Now the following ensures that events on both faces are processed
|
||||
* face1.processEvents();
|
||||
* // or face1.getIoService().run();
|
||||
* // or face1.getIoContext().run();
|
||||
* @endcode
|
||||
*
|
||||
* or
|
||||
*
|
||||
* @code
|
||||
* boost::asio::io_service ioService;
|
||||
* Face face1(ioService);
|
||||
* Face face2(ioService);
|
||||
*
|
||||
* ioService.run();
|
||||
* boost::asio::io_context ioCtx;
|
||||
* Face face1(ioCtx);
|
||||
* Face face2(ioCtx);
|
||||
* ioCtx.run();
|
||||
* @endcode
|
||||
*
|
||||
* @param ioService A reference to boost::io_service object that should control all
|
||||
* IO operations.
|
||||
* @param ioCtx A reference to the io_context object that should control all I/O operations.
|
||||
* @throw ConfigFile::Error the configuration file cannot be parsed or specifies an unsupported protocol
|
||||
*/
|
||||
explicit
|
||||
Face(boost::asio::io_service& ioService);
|
||||
Face(boost::asio::io_context& ioCtx);
|
||||
|
||||
/**
|
||||
* @brief Create Face using TcpTransport
|
||||
* @brief Create Face using TcpTransport.
|
||||
*
|
||||
* @param host IP address or hostname of the NDN forwarder
|
||||
* @param port port number or service name of the NDN forwarder (**default**: "6363")
|
||||
@@ -172,7 +170,7 @@ public: // constructors
|
||||
Face(const std::string& host, const std::string& port = "6363");
|
||||
|
||||
/**
|
||||
* @brief Create Face using given transport and KeyChain
|
||||
* @brief Create Face using the given Transport and KeyChain.
|
||||
* @param transport the transport for lower layer communication. If nullptr,
|
||||
* a default transport will be used.
|
||||
* @param keyChain the KeyChain to sign commands
|
||||
@@ -186,50 +184,50 @@ public: // constructors
|
||||
Face(shared_ptr<Transport> transport, KeyChain& keyChain);
|
||||
|
||||
/**
|
||||
* @brief Create Face using given transport and io_service
|
||||
* @brief Create Face using the given Transport and io_context.
|
||||
* @param transport the transport for lower layer communication. If nullptr,
|
||||
* a default transport will be used.
|
||||
* @param ioService the io_service that controls all IO operations
|
||||
* @param ioCtx the io_context that controls all I/O operations
|
||||
*
|
||||
* @sa Face(boost::asio::io_service&)
|
||||
* @sa Face(boost::asio::io_context&)
|
||||
* @sa Face(shared_ptr<Transport>)
|
||||
*
|
||||
* @throw ConfigFile::Error @p transport is nullptr, and the configuration file cannot be
|
||||
* parsed or specifies an unsupported protocol
|
||||
* @note shared_ptr is passed by value because ownership is shared with this class
|
||||
*/
|
||||
Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService);
|
||||
Face(shared_ptr<Transport> transport, boost::asio::io_context& ioCtx);
|
||||
|
||||
/**
|
||||
* @brief Create a new Face using given Transport and io_service
|
||||
* @brief Create Face using the given Transport, io_context, and KeyChain.
|
||||
* @param transport the transport for lower layer communication. If nullptr,
|
||||
* a default transport will be used.
|
||||
* @param ioService the io_service that controls all IO operations
|
||||
* @param ioCtx the io_context that controls all I/O operations
|
||||
* @param keyChain the KeyChain to sign commands
|
||||
*
|
||||
* @sa Face(boost::asio::io_service&)
|
||||
* @sa Face(boost::asio::io_context&)
|
||||
* @sa Face(shared_ptr<Transport>, KeyChain&)
|
||||
*
|
||||
* @throw ConfigFile::Error @p transport is nullptr, and the configuration file cannot be
|
||||
* parsed or specifies an unsupported protocol
|
||||
* @note shared_ptr is passed by value because ownership is shared with this class
|
||||
*/
|
||||
Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain);
|
||||
Face(shared_ptr<Transport> transport, boost::asio::io_context& ioCtx, KeyChain& keyChain);
|
||||
|
||||
virtual
|
||||
~Face();
|
||||
|
||||
public: // consumer
|
||||
/**
|
||||
* @brief Express Interest
|
||||
* @brief Express an Interest.
|
||||
* @param interest the Interest; a copy will be made, so that the caller is not
|
||||
* required to maintain the argument unchanged
|
||||
* @param afterSatisfied function to be invoked if Data is returned
|
||||
* @param afterNacked function to be invoked if Network NACK is returned
|
||||
* @param afterTimeout function to be invoked if neither Data nor Network NACK
|
||||
* is returned within InterestLifetime
|
||||
* @throw OversizedPacketError encoded Interest size exceeds MAX_NDN_PACKET_SIZE
|
||||
* @return A handle for canceling the pending Interest.
|
||||
* @throw OversizedPacketError Encoded Interest size exceeds #MAX_NDN_PACKET_SIZE.
|
||||
*/
|
||||
PendingInterestHandle
|
||||
expressInterest(const Interest& interest,
|
||||
@@ -238,13 +236,13 @@ public: // consumer
|
||||
const TimeoutCallback& afterTimeout);
|
||||
|
||||
/**
|
||||
* @brief Cancel all previously expressed Interests
|
||||
* @brief Cancel all previously expressed Interests.
|
||||
*/
|
||||
void
|
||||
removeAllPendingInterests();
|
||||
|
||||
/**
|
||||
* @brief Get number of pending Interests
|
||||
* @brief Get number of pending Interests.
|
||||
*/
|
||||
size_t
|
||||
getNPendingInterests() const;
|
||||
@@ -252,7 +250,7 @@ public: // consumer
|
||||
public: // producer
|
||||
/**
|
||||
* @brief Set InterestFilter to dispatch incoming matching interest to onInterest
|
||||
* callback and register the filtered prefix with the connected NDN forwarder
|
||||
* callback and register the filtered prefix with the connected NDN forwarder.
|
||||
*
|
||||
* This version of setInterestFilter combines setInterestFilter and registerPrefix
|
||||
* operations and is intended to be used when only one filter for the same prefix needed
|
||||
@@ -277,7 +275,7 @@ public: // producer
|
||||
|
||||
/**
|
||||
* @brief Set InterestFilter to dispatch incoming matching interest to onInterest
|
||||
* callback and register the filtered prefix with the connected NDN forwarder
|
||||
* callback and register the filtered prefix with the connected NDN forwarder.
|
||||
*
|
||||
* This version of setInterestFilter combines setInterestFilter and registerPrefix
|
||||
* operations and is intended to be used when only one filter for the same prefix needed
|
||||
@@ -318,7 +316,7 @@ public: // producer
|
||||
setInterestFilter(const InterestFilter& filter, const InterestCallback& onInterest);
|
||||
|
||||
/**
|
||||
* @brief Register prefix with the connected NDN forwarder
|
||||
* @brief Register prefix with the connected NDN forwarder.
|
||||
*
|
||||
* This method only modifies forwarder's RIB and does not associate any
|
||||
* onInterest callbacks. Use setInterestFilter method to dispatch incoming Interests to
|
||||
@@ -342,62 +340,63 @@ public: // producer
|
||||
uint64_t flags = nfd::ROUTE_FLAG_CHILD_INHERIT);
|
||||
|
||||
/**
|
||||
* @brief Publish data packet
|
||||
* @param data the Data; a copy will be made, so that the caller is not required to
|
||||
* maintain the argument unchanged
|
||||
* @brief Publish a Data packet.
|
||||
* @param data The Data packet; a copy will be made, so that the caller is not required to
|
||||
* maintain the argument unchanged.
|
||||
*
|
||||
* This method can be called to satisfy incoming Interests, or to add Data packet into the cache
|
||||
* of the local NDN forwarder if forwarder is configured to accept unsolicited Data.
|
||||
*
|
||||
* @throw OversizedPacketError encoded Data size exceeds MAX_NDN_PACKET_SIZE
|
||||
* @throw OversizedPacketError Encoded Data size exceeds #MAX_NDN_PACKET_SIZE.
|
||||
*/
|
||||
void
|
||||
put(Data data);
|
||||
put(const Data& data);
|
||||
|
||||
/**
|
||||
* @brief Send a network NACK
|
||||
* @param nack the Nack; a copy will be made, so that the caller is not required to
|
||||
* maintain the argument unchanged
|
||||
* @throw OversizedPacketError encoded Nack size exceeds MAX_NDN_PACKET_SIZE
|
||||
* @brief Send a %Network Nack.
|
||||
* @param nack The Nack packet; a copy will be made, so that the caller is not required to
|
||||
* maintain the argument unchanged.
|
||||
* @throw OversizedPacketError Encoded Nack size exceeds #MAX_NDN_PACKET_SIZE.
|
||||
*/
|
||||
void
|
||||
put(lp::Nack nack);
|
||||
put(const lp::Nack& nack);
|
||||
|
||||
public: // IO routine
|
||||
public: // event loop routines
|
||||
/**
|
||||
* @brief Process any data to receive or call timeout callbacks.
|
||||
* @brief Run the event loop to process any pending work and execute completion handlers.
|
||||
*
|
||||
* This call will block forever (with the default timeout of 0) to process I/O on the face.
|
||||
* This call will block forever (with the default @p timeout of 0) to process I/O on the face.
|
||||
* To exit cleanly on a producer, clear any Interest filters and wait for processEvents() to
|
||||
* return. To exit after an error, one can call shutdown().
|
||||
* In consumer applications, processEvents() will return when all expressed Interests have been
|
||||
* satisfied, Nacked, or timed out. To terminate earlier, a consumer application should cancel
|
||||
* all previously expressed and still-pending Interests.
|
||||
*
|
||||
* If a positive timeout is specified, then processEvents() will exit after this timeout, provided
|
||||
* it is not stopped earlier with shutdown() or when all active events finish. processEvents()
|
||||
* can be called repeatedly, if desired.
|
||||
* If @p timeout is a positive value, then processEvents() will return after the specified
|
||||
* duration has elapsed, unless the event loop is stopped earlier with shutdown() or runs
|
||||
* out of work to do.
|
||||
*
|
||||
* If a negative timeout is specified, then processEvents will not block and will process only
|
||||
* pending events.
|
||||
* If a negative @p timeout is specified, then processEvents() will not block and will process
|
||||
* only handlers that are ready to run.
|
||||
*
|
||||
* @param timeout maximum time to block the thread
|
||||
* @param keepThread Keep thread in a blocked state (in event processing), even when
|
||||
* processEvents() can be called repeatedly, if desired.
|
||||
*
|
||||
* @param timeout Maximum amount of time to block the event loop (see above).
|
||||
* @param keepRunning Keep thread in a blocked state (in event processing), even when
|
||||
* there are no outstanding events (e.g., no Interest/Data is expected).
|
||||
* If timeout is zero and this parameter is true, the only way to stop
|
||||
* processEvents() is to call shutdown().
|
||||
* Ignored if @p timeout is negative. If @p timeout is 0 and @p keepRunning
|
||||
* is true, the only way to stop processEvents() is to call shutdown().
|
||||
*
|
||||
* @note This may throw an exception for reading data or in the callback for processing
|
||||
* the data. If you call this from an main event loop, you may want to catch and
|
||||
* log/disregard all exceptions.
|
||||
*
|
||||
* @throw OversizedPacketError encoded packet size exceeds MAX_NDN_PACKET_SIZE
|
||||
* @throw OversizedPacketError Encoded packet size exceeds #MAX_NDN_PACKET_SIZE.
|
||||
*/
|
||||
void
|
||||
processEvents(time::milliseconds timeout = time::milliseconds::zero(),
|
||||
bool keepThread = false)
|
||||
processEvents(time::milliseconds timeout = 0_ms, bool keepRunning = false)
|
||||
{
|
||||
this->doProcessEvents(timeout, keepThread);
|
||||
this->doProcessEvents(timeout, keepRunning);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -405,8 +404,8 @@ public: // IO routine
|
||||
*
|
||||
* This method cancels all pending operations and closes the connection to the NDN forwarder.
|
||||
*
|
||||
* Note that this method does not stop the io_service if it is shared between multiple Faces or
|
||||
* with other IO objects (e.g., Scheduler).
|
||||
* Note that this method does not stop the io_context if it is shared between multiple Faces or
|
||||
* with other I/O objects (e.g., Scheduler).
|
||||
*
|
||||
* @warning Calling this method may cause outgoing packets to be lost. Producers that shut down
|
||||
* immediately after sending a Data packet should instead clear all Interest filters to
|
||||
@@ -417,35 +416,39 @@ public: // IO routine
|
||||
shutdown();
|
||||
|
||||
/**
|
||||
* @brief Returns a reference to the io_service used by this face.
|
||||
* @brief Returns a reference to the io_context used by this face.
|
||||
*/
|
||||
boost::asio::io_service&
|
||||
getIoService()
|
||||
boost::asio::io_context&
|
||||
getIoContext() const noexcept
|
||||
{
|
||||
return m_ioService;
|
||||
return m_ioCtx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use getIoContext()
|
||||
*/
|
||||
[[deprecated("use getIoContext")]]
|
||||
boost::asio::io_context&
|
||||
getIoService() const noexcept
|
||||
{
|
||||
return m_ioCtx;
|
||||
}
|
||||
|
||||
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
|
||||
/**
|
||||
* @brief Returns the underlying transport.
|
||||
*/
|
||||
shared_ptr<Transport>
|
||||
Transport&
|
||||
getTransport() const
|
||||
{
|
||||
return m_transport;
|
||||
return *m_transport;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void
|
||||
doProcessEvents(time::milliseconds timeout, bool keepThread);
|
||||
doProcessEvents(time::milliseconds timeout, bool keepRunning);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @throw ConfigFile::Error on parse error and unsupported protocols
|
||||
*/
|
||||
shared_ptr<Transport>
|
||||
makeDefaultTransport();
|
||||
|
||||
/**
|
||||
* @throw Face::Error on unsupported protocol
|
||||
*/
|
||||
@@ -456,10 +459,10 @@ private:
|
||||
onReceiveElement(const Block& blockFromDaemon);
|
||||
|
||||
private:
|
||||
/// the io_service owned by this Face, may be null
|
||||
unique_ptr<boost::asio::io_service> m_internalIoService;
|
||||
/// the io_service used by this Face
|
||||
boost::asio::io_service& m_ioService;
|
||||
/// The io_context owned by this Face, may be null if using an externally provided io_context.
|
||||
unique_ptr<boost::asio::io_context> m_internalIoCtx;
|
||||
/// The io_context used by this Face.
|
||||
boost::asio::io_context& m_ioCtx;
|
||||
|
||||
shared_ptr<Transport> m_transport;
|
||||
|
||||
@@ -517,11 +520,7 @@ using ScopedPendingInterestHandle = detail::ScopedCancelHandle<PendingInterestHa
|
||||
class RegisteredPrefixHandle : public detail::CancelHandle
|
||||
{
|
||||
public:
|
||||
RegisteredPrefixHandle() noexcept
|
||||
{
|
||||
// This could have been '= default', but there's compiler bug in Apple clang 9.0.0,
|
||||
// see https://stackoverflow.com/a/44693603
|
||||
}
|
||||
RegisteredPrefixHandle() noexcept = default;
|
||||
|
||||
/** \brief Unregister the prefix.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -26,12 +26,14 @@
|
||||
// and included before anything else
|
||||
|
||||
#include "ndn-cxx/detail/common.hpp"
|
||||
#include "ndn-cxx/security/impl/openssl.hpp"
|
||||
|
||||
// STL headers to precompile
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <list>
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
@@ -43,6 +45,7 @@
|
||||
#include <boost/asio/basic_socket.hpp>
|
||||
#include <boost/bind/bind.hpp>
|
||||
#include <boost/chrono.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
@@ -52,6 +55,7 @@
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#endif // NDN_CXX_IMPL_COMMON_PCH_HPP
|
||||
+42
-35
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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,17 +27,21 @@
|
||||
#include "ndn-cxx/impl/lp-field-tag.hpp"
|
||||
#include "ndn-cxx/impl/pending-interest.hpp"
|
||||
#include "ndn-cxx/impl/registered-prefix.hpp"
|
||||
#include "ndn-cxx/lp/fields.hpp"
|
||||
#include "ndn-cxx/lp/packet.hpp"
|
||||
#include "ndn-cxx/lp/tags.hpp"
|
||||
#include "ndn-cxx/mgmt/nfd/command-options.hpp"
|
||||
#include "ndn-cxx/mgmt/nfd/controller.hpp"
|
||||
#include "ndn-cxx/transport/tcp-transport.hpp"
|
||||
#include "ndn-cxx/transport/unix-transport.hpp"
|
||||
#include "ndn-cxx/transport/transport.hpp"
|
||||
#include "ndn-cxx/util/logger.hpp"
|
||||
#include "ndn-cxx/util/scheduler.hpp"
|
||||
#include "ndn-cxx/util/signal.hpp"
|
||||
|
||||
NDN_LOG_INIT(ndn.Face);
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
namespace ndn {
|
||||
|
||||
//
|
||||
// INFO level: prefix registration, etc.
|
||||
//
|
||||
// DEBUG level: packet logging.
|
||||
@@ -50,17 +54,18 @@ NDN_LOG_INIT(ndn.Face);
|
||||
// DEBUG level.
|
||||
//
|
||||
// TRACE level: more detailed unstructured messages.
|
||||
//
|
||||
NDN_LOG_INIT(ndn.Face);
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** @brief implementation detail of Face
|
||||
/**
|
||||
* @brief Implementation detail of Face.
|
||||
*/
|
||||
class Face::Impl : public std::enable_shared_from_this<Face::Impl>
|
||||
{
|
||||
public:
|
||||
Impl(Face& face, KeyChain& keyChain)
|
||||
: m_face(face)
|
||||
, m_scheduler(m_face.getIoService())
|
||||
, m_scheduler(m_face.getIoContext())
|
||||
, m_nfdController(m_face, keyChain)
|
||||
{
|
||||
auto onEmptyPitOrNoRegisteredPrefixes = [this] {
|
||||
@@ -68,10 +73,10 @@ public:
|
||||
// (+async_read) from within onInterest/onData callback. After onInterest/onData
|
||||
// finishes, there is another +async_read with the same memory block. A few of such
|
||||
// async_read duplications can cause various effects and result in segfault.
|
||||
m_face.getIoService().post([this] {
|
||||
boost::asio::post(m_face.getIoContext(), [this] {
|
||||
if (m_pendingInterestTable.empty() && m_registeredPrefixTable.empty()) {
|
||||
m_face.m_transport->pause();
|
||||
if (!m_ioServiceWork) {
|
||||
if (!m_workGuard) {
|
||||
m_processEventsTimeoutEvent.cancel();
|
||||
}
|
||||
}
|
||||
@@ -109,9 +114,8 @@ public: // consumer
|
||||
void
|
||||
asyncRemovePendingInterest(detail::RecordId id)
|
||||
{
|
||||
m_face.getIoService().post([id, w = weak_ptr<Impl>{shared_from_this()}] { // use weak_from_this() in C++17
|
||||
auto impl = w.lock();
|
||||
if (impl != nullptr) {
|
||||
boost::asio::post(m_face.getIoContext(), [id, w = weak_from_this()] {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->m_pendingInterestTable.erase(id);
|
||||
}
|
||||
});
|
||||
@@ -123,7 +127,8 @@ public: // consumer
|
||||
m_pendingInterestTable.clear();
|
||||
}
|
||||
|
||||
/** @return whether the Data should be sent to the forwarder, if it does not come from the forwarder
|
||||
/**
|
||||
* @return Whether the Data should be sent to the forwarder, if it does not come from the forwarder.
|
||||
*/
|
||||
bool
|
||||
satisfyPendingInterests(const Data& data)
|
||||
@@ -150,19 +155,20 @@ public: // consumer
|
||||
return hasForwarderMatch || !hasAppMatch;
|
||||
}
|
||||
|
||||
/** @return a Nack to be sent to the forwarder, or nullopt if no Nack should be sent
|
||||
/**
|
||||
* @return A Nack to be sent to the forwarder, or nullopt if no Nack should be sent.
|
||||
*/
|
||||
optional<lp::Nack>
|
||||
std::optional<lp::Nack>
|
||||
nackPendingInterests(const lp::Nack& nack)
|
||||
{
|
||||
optional<lp::Nack> outNack;
|
||||
std::optional<lp::Nack> outNack;
|
||||
m_pendingInterestTable.removeIf([&] (PendingInterest& entry) {
|
||||
if (!nack.getInterest().matchesInterest(*entry.getInterest())) {
|
||||
return false;
|
||||
}
|
||||
NDN_LOG_DEBUG(" nacking " << *entry.getInterest() << " from " << entry.getOrigin());
|
||||
|
||||
optional<lp::Nack> outNack1 = entry.recordNack(nack);
|
||||
auto outNack1 = entry.recordNack(nack);
|
||||
if (!outNack1) {
|
||||
return false;
|
||||
}
|
||||
@@ -193,9 +199,8 @@ public: // producer
|
||||
void
|
||||
asyncUnsetInterestFilter(detail::RecordId id)
|
||||
{
|
||||
m_face.getIoService().post([id, w = weak_ptr<Impl>{shared_from_this()}] { // use weak_from_this() in C++17
|
||||
auto impl = w.lock();
|
||||
if (impl != nullptr) {
|
||||
boost::asio::post(m_face.getIoContext(), [id, w = weak_from_this()] {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->unsetInterestFilter(id);
|
||||
}
|
||||
});
|
||||
@@ -232,7 +237,7 @@ public: // producer
|
||||
putNack(const lp::Nack& nack)
|
||||
{
|
||||
NDN_LOG_DEBUG("<N " << nack.getInterest() << '~' << nack.getHeader().getReason());
|
||||
optional<lp::Nack> outNack = nackPendingInterests(nack);
|
||||
auto outNack = nackPendingInterests(nack);
|
||||
if (!outNack) {
|
||||
return;
|
||||
}
|
||||
@@ -253,8 +258,10 @@ public: // prefix registration
|
||||
registerPrefix(const Name& prefix,
|
||||
const RegisterPrefixSuccessCallback& onSuccess,
|
||||
const RegisterPrefixFailureCallback& onFailure,
|
||||
uint64_t flags, const nfd::CommandOptions& options,
|
||||
const optional<InterestFilter>& filter, const InterestCallback& onInterest)
|
||||
uint64_t flags,
|
||||
const nfd::CommandOptions& options,
|
||||
const std::optional<InterestFilter>& filter,
|
||||
const InterestCallback& onInterest)
|
||||
{
|
||||
NDN_LOG_INFO("registering prefix: " << prefix);
|
||||
auto id = m_registeredPrefixTable.allocateId();
|
||||
@@ -290,9 +297,8 @@ public: // prefix registration
|
||||
const UnregisterPrefixSuccessCallback& onSuccess,
|
||||
const UnregisterPrefixFailureCallback& onFailure)
|
||||
{
|
||||
m_face.getIoService().post([=, w = weak_ptr<Impl>{shared_from_this()}] { // use weak_from_this() in C++17
|
||||
auto impl = w.lock();
|
||||
if (impl != nullptr) {
|
||||
boost::asio::post(m_face.getIoContext(), [=, w = weak_from_this()] {
|
||||
if (auto impl = w.lock(); impl != nullptr) {
|
||||
impl->unregisterPrefix(id, onSuccess, onFailure);
|
||||
}
|
||||
});
|
||||
@@ -302,12 +308,12 @@ public: // IO routine
|
||||
void
|
||||
ensureConnected(bool wantResume)
|
||||
{
|
||||
if (!m_face.m_transport->isConnected()) {
|
||||
m_face.m_transport->connect(m_face.getIoService(),
|
||||
if (m_face.m_transport->getState() == Transport::State::CLOSED) {
|
||||
m_face.m_transport->connect(m_face.getIoContext(),
|
||||
[this] (const Block& wire) { m_face.onReceiveElement(wire); });
|
||||
}
|
||||
|
||||
if (wantResume && !m_face.m_transport->isReceiving()) {
|
||||
if (wantResume) {
|
||||
m_face.m_transport->resume();
|
||||
}
|
||||
}
|
||||
@@ -315,13 +321,13 @@ public: // IO routine
|
||||
void
|
||||
shutdown()
|
||||
{
|
||||
m_ioServiceWork.reset();
|
||||
m_workGuard.reset();
|
||||
m_pendingInterestTable.clear();
|
||||
m_registeredPrefixTable.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
/** @brief Finish packet encoding
|
||||
/** @brief Finish packet encoding.
|
||||
* @param lpPacket NDNLP packet without FragmentField
|
||||
* @param wire wire encoding of Interest or Data
|
||||
* @param pktType packet type, 'I' for Interest, 'D' for Data, 'N' for Nack
|
||||
@@ -333,7 +339,7 @@ private:
|
||||
finishEncoding(lp::Packet&& lpPacket, Block wire, char pktType, const Name& name)
|
||||
{
|
||||
if (!lpPacket.empty()) {
|
||||
lpPacket.add<lp::FragmentField>(std::make_pair(wire.begin(), wire.end()));
|
||||
lpPacket.add<lp::FragmentField>({wire.begin(), wire.end()});
|
||||
wire = lpPacket.wireEncode();
|
||||
}
|
||||
|
||||
@@ -414,7 +420,8 @@ private:
|
||||
detail::RecordContainer<InterestFilterRecord> m_interestFilterTable;
|
||||
detail::RecordContainer<RegisteredPrefix> m_registeredPrefixTable;
|
||||
|
||||
unique_ptr<boost::asio::io_service::work> m_ioServiceWork; // if thread needs to be preserved
|
||||
using IoContextWorkGuard = boost::asio::executor_work_guard<boost::asio::io_context::executor_type>;
|
||||
unique_ptr<IoContextWorkGuard> m_workGuard;
|
||||
|
||||
friend Face;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -34,7 +34,7 @@ class InterestFilterRecord : public detail::RecordBase<InterestFilterRecord>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct an Interest filter record
|
||||
* @brief Constructor.
|
||||
*
|
||||
* @param filter an InterestFilter that represents what Interest should invoke the callback
|
||||
* @param callback invoked when matching Interest is received
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if Interest name matches the filter
|
||||
* @brief Check if Interest name matches the filter.
|
||||
* @param name Interest Name
|
||||
*/
|
||||
bool
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief invokes the InterestCallback
|
||||
* @brief Invokes the InterestCallback.
|
||||
* @note This method does nothing if the Interest callback is empty
|
||||
*/
|
||||
void
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2022 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).
|
||||
*
|
||||
@@ -29,11 +29,11 @@
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace ndn {
|
||||
namespace name {
|
||||
namespace detail {
|
||||
namespace ndn::name {
|
||||
namespace {
|
||||
|
||||
/** \brief Declare rules for a NameComponent type.
|
||||
/**
|
||||
* \brief Declare rules for a NameComponent type.
|
||||
*/
|
||||
class ComponentType : noncopyable
|
||||
{
|
||||
@@ -43,25 +43,28 @@ public:
|
||||
virtual
|
||||
~ComponentType() = default;
|
||||
|
||||
/** \brief Throw Component::Error if \p comp is invalid.
|
||||
/**
|
||||
* \brief Throw Component::Error if \p comp is invalid.
|
||||
*/
|
||||
virtual void
|
||||
check(const Component& comp) const
|
||||
{
|
||||
}
|
||||
|
||||
/** \brief Calculate the successor of \p comp.
|
||||
/**
|
||||
* \brief Calculate the successor of \p comp.
|
||||
*
|
||||
* If \p comp is the maximum possible value of this component type, return true to indicate
|
||||
* that the successor should have a greater TLV-TYPE.
|
||||
* If \p comp is the maximum possible value of this component type, return true to indicate
|
||||
* that the successor should have a greater TLV-TYPE.
|
||||
*/
|
||||
virtual std::tuple<bool, Component>
|
||||
getSuccessor(const Component& comp) const
|
||||
{
|
||||
return {false, std::get<Block>(getSuccessorImpl(comp))};
|
||||
return {false, Component(std::get<Block>(getSuccessorImpl(comp)))};
|
||||
}
|
||||
|
||||
/** \brief Return the minimum allowable TLV-VALUE of this component type.
|
||||
/**
|
||||
* \brief Return the minimum allowable TLV-VALUE of this component type.
|
||||
*/
|
||||
virtual span<const uint8_t>
|
||||
getMinValue() const
|
||||
@@ -70,36 +73,39 @@ public:
|
||||
return value;
|
||||
}
|
||||
|
||||
/** \brief Return the prefix of the alternate URI representation.
|
||||
/**
|
||||
* \brief Return the prefix of the alternate URI representation.
|
||||
*
|
||||
* NDN URI specification allows a name component type to declare an alternate URI representation
|
||||
* in the form of `<prefix>=<value>`, in addition to the plain `<type-number>=<escaped-value>`
|
||||
* syntax.
|
||||
* NDN URI specification allows a name component type to declare an alternate URI representation
|
||||
* in the form of `<prefix>=<value>`, in addition to the plain `<type-number>=<escaped-value>`
|
||||
* syntax.
|
||||
*
|
||||
* \return the `<prefix>` portion of the alternate URI representation.
|
||||
* \retval nullptr this component does not have an alternate URI representation.
|
||||
* \return The `<prefix>` portion of the alternate URI representation.
|
||||
* \retval empty This component does not have an alternate URI representation.
|
||||
*/
|
||||
virtual const char*
|
||||
virtual std::string_view
|
||||
getAltUriPrefix() const
|
||||
{
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
/** \brief Parse component from alternate URI representation.
|
||||
* \param input the `<value>` portion of the alternate URI representation.
|
||||
* \throw Component::Error
|
||||
* \pre getAltUriPrefix() != nullptr
|
||||
/**
|
||||
* \brief Parse component from alternate URI representation.
|
||||
* \param input the `<value>` portion of the alternate URI representation.
|
||||
* \throw Component::Error
|
||||
* \pre `getAltUriPrefix().empty() == false`
|
||||
*/
|
||||
virtual Component
|
||||
parseAltUriValue(const std::string&) const
|
||||
parseAltUriValue(std::string_view input) const
|
||||
{
|
||||
NDN_CXX_UNREACHABLE;
|
||||
}
|
||||
|
||||
/** \brief Write URI representation of \p comp to \p os.
|
||||
/**
|
||||
* \brief Write URI representation of \p comp to \p os.
|
||||
*
|
||||
* This base class implementation encodes the component using the plain
|
||||
* `<type-number>=<escaped-value>` syntax (aka canonical format).
|
||||
* This base class implementation encodes the component using the plain
|
||||
* `<type-number>=<escaped-value>` syntax (aka canonical format).
|
||||
*/
|
||||
virtual void
|
||||
writeUri(std::ostream& os, const Component& comp) const
|
||||
@@ -109,11 +115,12 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
/** \brief Calculate the successor of \p comp, extending TLV-LENGTH if value overflows.
|
||||
* \return whether TLV-LENGTH was extended, and the successor
|
||||
/**
|
||||
* \brief Calculate the successor of \p comp, extending TLV-LENGTH if value overflows.
|
||||
* \return Whether TLV-LENGTH was extended, and the successor.
|
||||
*/
|
||||
std::tuple<bool, Block>
|
||||
getSuccessorImpl(const Component& comp) const
|
||||
static std::tuple<bool, Block>
|
||||
getSuccessorImpl(const Component& comp)
|
||||
{
|
||||
EncodingBuffer encoder(comp.size() + 9, 9);
|
||||
// leave room for additional byte when TLV-VALUE overflows, and for TLV-LENGTH size increase
|
||||
@@ -137,24 +144,26 @@ protected:
|
||||
return {isOverflow, encoder.block()};
|
||||
}
|
||||
|
||||
/** \brief Write TLV-VALUE as `<escaped-value>` of NDN URI syntax.
|
||||
/**
|
||||
* \brief Write TLV-VALUE as `<escaped-value>` of NDN URI syntax.
|
||||
*/
|
||||
void
|
||||
writeUriEscapedValue(std::ostream& os, const Component& comp) const
|
||||
static void
|
||||
writeUriEscapedValue(std::ostream& os, const Component& comp)
|
||||
{
|
||||
bool isAllPeriods = std::all_of(comp.value_begin(), comp.value_end(),
|
||||
[] (uint8_t x) { return x == '.'; });
|
||||
if (isAllPeriods) {
|
||||
os << "...";
|
||||
}
|
||||
escape(os, reinterpret_cast<const char*>(comp.value()), comp.value_size());
|
||||
escape(os, {reinterpret_cast<const char*>(comp.value()), comp.value_size()});
|
||||
}
|
||||
};
|
||||
|
||||
/** \brief Rules for GenericNameComponent.
|
||||
/**
|
||||
* \brief Rules for GenericNameComponent.
|
||||
*
|
||||
* GenericNameComponent has an alternate URI representation that omits the `<type-number>` prefix.
|
||||
* This must be special-cased in the caller, and is not handled by this class.
|
||||
* GenericNameComponent has an alternate URI representation that omits the `<type-number>` prefix.
|
||||
* This must be special-cased in the caller, and is not handled by this class.
|
||||
*/
|
||||
class GenericNameComponentType final : public ComponentType
|
||||
{
|
||||
@@ -166,56 +175,36 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/** \brief Rules for a component type holding a SHA256 digest value, written as
|
||||
* a hex string in URI representation.
|
||||
/**
|
||||
* \brief Rules for a component type holding a SHA256 digest value, written as
|
||||
* a hex string in URI representation.
|
||||
*/
|
||||
class Sha256ComponentType final : public ComponentType
|
||||
{
|
||||
public:
|
||||
Sha256ComponentType(uint32_t type, const std::string& typeName, const std::string& uriPrefix)
|
||||
constexpr
|
||||
Sha256ComponentType(uint32_t type, std::string_view typeName, std::string_view uriPrefix)
|
||||
: m_type(type)
|
||||
, m_typeName(typeName)
|
||||
, m_uriPrefix(uriPrefix)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
match(const Component& comp) const
|
||||
{
|
||||
return comp.type() == m_type && comp.value_size() == util::Sha256::DIGEST_SIZE;
|
||||
}
|
||||
|
||||
void
|
||||
check(const Component& comp) const final
|
||||
{
|
||||
BOOST_ASSERT(comp.type() == m_type);
|
||||
if (comp.value_size() != util::Sha256::DIGEST_SIZE) {
|
||||
NDN_THROW(Error(m_typeName + " TLV-LENGTH must be " + to_string(util::Sha256::DIGEST_SIZE)));
|
||||
NDN_THROW(Error(std::string(m_typeName) + " TLV-LENGTH must be " +
|
||||
std::to_string(util::Sha256::DIGEST_SIZE)));
|
||||
}
|
||||
}
|
||||
|
||||
Component
|
||||
create(ConstBufferPtr value) const
|
||||
{
|
||||
return Block(m_type, std::move(value));
|
||||
}
|
||||
|
||||
Component
|
||||
create(span<const uint8_t> value) const
|
||||
{
|
||||
return makeBinaryBlock(m_type, value);
|
||||
}
|
||||
|
||||
std::tuple<bool, Component>
|
||||
getSuccessor(const Component& comp) const final
|
||||
{
|
||||
bool isExtended = false;
|
||||
Block successor;
|
||||
std::tie(isExtended, successor) = getSuccessorImpl(comp);
|
||||
if (isExtended) {
|
||||
return {true, comp};
|
||||
}
|
||||
return {false, Component(successor)};
|
||||
auto [isExtended, successor] = getSuccessorImpl(comp);
|
||||
return {isExtended, isExtended ? comp : Component(successor)};
|
||||
}
|
||||
|
||||
span<const uint8_t>
|
||||
@@ -225,61 +214,47 @@ public:
|
||||
return value;
|
||||
}
|
||||
|
||||
const char*
|
||||
std::string_view
|
||||
getAltUriPrefix() const final
|
||||
{
|
||||
return m_uriPrefix.data();
|
||||
return m_uriPrefix;
|
||||
}
|
||||
|
||||
Component
|
||||
parseAltUriValue(const std::string& input) const final
|
||||
parseAltUriValue(std::string_view input) const final
|
||||
{
|
||||
shared_ptr<Buffer> value;
|
||||
try {
|
||||
value = fromHex(input);
|
||||
}
|
||||
catch (const StringHelperError&) {
|
||||
NDN_THROW(Error("Cannot convert to " + m_typeName + " (invalid hex encoding)"));
|
||||
NDN_THROW(Error("Cannot convert to " + std::string(m_typeName) + " (invalid hex encoding)"));
|
||||
}
|
||||
return Component(m_type, std::move(value));
|
||||
return {m_type, std::move(value)};
|
||||
}
|
||||
|
||||
void
|
||||
writeUri(std::ostream& os, const Component& comp) const final
|
||||
{
|
||||
os << m_uriPrefix << '=';
|
||||
printHex(os, comp.value(), comp.value_size(), false);
|
||||
printHex(os, comp.value_bytes(), false);
|
||||
}
|
||||
|
||||
private:
|
||||
const uint32_t m_type;
|
||||
const std::string m_typeName;
|
||||
const std::string m_uriPrefix;
|
||||
const std::string_view m_typeName;
|
||||
const std::string_view m_uriPrefix;
|
||||
};
|
||||
|
||||
inline const Sha256ComponentType&
|
||||
getComponentType1()
|
||||
{
|
||||
static const Sha256ComponentType ct1(tlv::ImplicitSha256DigestComponent,
|
||||
"ImplicitSha256DigestComponent", "sha256digest");
|
||||
return ct1;
|
||||
}
|
||||
|
||||
inline const Sha256ComponentType&
|
||||
getComponentType2()
|
||||
{
|
||||
static const Sha256ComponentType ct2(tlv::ParametersSha256DigestComponent,
|
||||
"ParametersSha256DigestComponent", "params-sha256");
|
||||
return ct2;
|
||||
}
|
||||
|
||||
/** \brief Rules for a component type holding a NonNegativeInteger value, written as
|
||||
* a decimal number in URI representation.
|
||||
/**
|
||||
* \brief Rules for a component type holding a NonNegativeInteger value, written as
|
||||
* a decimal number in URI representation.
|
||||
*/
|
||||
class DecimalComponentType final : public ComponentType
|
||||
{
|
||||
public:
|
||||
DecimalComponentType(uint32_t type, const std::string& typeName, const std::string& uriPrefix)
|
||||
constexpr
|
||||
DecimalComponentType(uint32_t type, std::string_view typeName, std::string_view uriPrefix)
|
||||
: m_type(type)
|
||||
, m_typeName(typeName)
|
||||
, m_uriPrefix(uriPrefix)
|
||||
@@ -291,27 +266,27 @@ public:
|
||||
// NonNegativeInteger, because the application may be using the same typed component
|
||||
// with different syntax and semantics.
|
||||
|
||||
const char*
|
||||
std::string_view
|
||||
getAltUriPrefix() const final
|
||||
{
|
||||
return m_uriPrefix.data();
|
||||
return m_uriPrefix;
|
||||
}
|
||||
|
||||
Component
|
||||
parseAltUriValue(const std::string& input) const final
|
||||
parseAltUriValue(std::string_view input) const final
|
||||
{
|
||||
uint64_t n = 0;
|
||||
try {
|
||||
n = std::stoull(input);
|
||||
n = std::stoull(std::string(input));
|
||||
}
|
||||
catch (const std::invalid_argument&) {
|
||||
NDN_THROW(Error("Cannot convert to " + m_typeName + " (invalid format)"));
|
||||
NDN_THROW(Error("Cannot convert to " + std::string(m_typeName) + " (invalid format)"));
|
||||
}
|
||||
catch (const std::out_of_range&) {
|
||||
NDN_THROW(Error("Cannot convert to " + m_typeName + " (out of range)"));
|
||||
NDN_THROW(Error("Cannot convert to " + std::string(m_typeName) + " (out of range)"));
|
||||
}
|
||||
if (to_string(n) != input) {
|
||||
NDN_THROW(Error("Cannot convert to " + m_typeName + " (invalid format)"));
|
||||
if (std::to_string(n) != input) {
|
||||
NDN_THROW(Error("Cannot convert to " + std::string(m_typeName) + " (invalid format)"));
|
||||
}
|
||||
return Component::fromNumber(n, m_type);
|
||||
}
|
||||
@@ -329,18 +304,20 @@ public:
|
||||
|
||||
private:
|
||||
const uint32_t m_type;
|
||||
const std::string m_typeName;
|
||||
const std::string m_uriPrefix;
|
||||
const std::string_view m_typeName;
|
||||
const std::string_view m_uriPrefix;
|
||||
};
|
||||
|
||||
/** \brief Rules regarding NameComponent types.
|
||||
/**
|
||||
* \brief Encapsulates the rules for different NameComponent types.
|
||||
*/
|
||||
class ComponentTypeTable : noncopyable
|
||||
{
|
||||
public:
|
||||
ComponentTypeTable();
|
||||
|
||||
/** \brief Retrieve ComponentType by TLV-TYPE.
|
||||
/**
|
||||
* \brief Retrieve a ComponentType by its TLV-TYPE.
|
||||
*/
|
||||
const ComponentType&
|
||||
get(uint32_t type) const
|
||||
@@ -351,16 +328,16 @@ public:
|
||||
return *m_table[type];
|
||||
}
|
||||
|
||||
/** \brief Retrieve ComponentType by alternate URI prefix.
|
||||
/**
|
||||
* \brief Retrieve a ComponentType by its alternate URI prefix.
|
||||
*/
|
||||
const ComponentType*
|
||||
findByUriPrefix(const std::string& prefix) const
|
||||
findByUriPrefix(std::string_view prefix) const
|
||||
{
|
||||
auto it = m_uriPrefixes.find(prefix);
|
||||
if (it == m_uriPrefixes.end()) {
|
||||
return nullptr;
|
||||
if (auto it = m_uriPrefixes.find(prefix); it != m_uriPrefixes.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -368,7 +345,7 @@ private:
|
||||
set(uint32_t type, const ComponentType& ct)
|
||||
{
|
||||
m_table.at(type) = &ct;
|
||||
if (ct.getAltUriPrefix() != nullptr) {
|
||||
if (!ct.getAltUriPrefix().empty()) {
|
||||
m_uriPrefixes[ct.getAltUriPrefix()] = &ct;
|
||||
}
|
||||
}
|
||||
@@ -376,7 +353,7 @@ private:
|
||||
private:
|
||||
const ComponentType m_baseType;
|
||||
std::array<const ComponentType*, 60> m_table;
|
||||
std::unordered_map<std::string, const ComponentType*> m_uriPrefixes;
|
||||
std::unordered_map<std::string_view, const ComponentType*> m_uriPrefixes;
|
||||
};
|
||||
|
||||
inline
|
||||
@@ -384,25 +361,33 @@ ComponentTypeTable::ComponentTypeTable()
|
||||
{
|
||||
m_table.fill(nullptr);
|
||||
|
||||
set(tlv::ImplicitSha256DigestComponent, getComponentType1());
|
||||
set(tlv::ParametersSha256DigestComponent, getComponentType2());
|
||||
static const Sha256ComponentType ct1(tlv::ImplicitSha256DigestComponent,
|
||||
"ImplicitSha256DigestComponent"sv, "sha256digest"sv);
|
||||
set(tlv::ImplicitSha256DigestComponent, ct1);
|
||||
static const Sha256ComponentType ct2(tlv::ParametersSha256DigestComponent,
|
||||
"ParametersSha256DigestComponent"sv, "params-sha256"sv);
|
||||
set(tlv::ParametersSha256DigestComponent, ct2);
|
||||
|
||||
static const GenericNameComponentType ct8;
|
||||
set(tlv::GenericNameComponent, ct8);
|
||||
|
||||
static const DecimalComponentType ct50(tlv::SegmentNameComponent, "SegmentNameComponent", "seg");
|
||||
static const ComponentType ct32;
|
||||
set(tlv::KeywordNameComponent, ct32);
|
||||
|
||||
static const DecimalComponentType ct50(tlv::SegmentNameComponent, "SegmentNameComponent"sv, "seg"sv);
|
||||
set(tlv::SegmentNameComponent, ct50);
|
||||
static const DecimalComponentType ct52(tlv::ByteOffsetNameComponent, "ByteOffsetNameComponent", "off");
|
||||
static const DecimalComponentType ct52(tlv::ByteOffsetNameComponent, "ByteOffsetNameComponent"sv, "off"sv);
|
||||
set(tlv::ByteOffsetNameComponent, ct52);
|
||||
static const DecimalComponentType ct54(tlv::VersionNameComponent, "VersionNameComponent", "v");
|
||||
static const DecimalComponentType ct54(tlv::VersionNameComponent, "VersionNameComponent"sv, "v"sv);
|
||||
set(tlv::VersionNameComponent, ct54);
|
||||
static const DecimalComponentType ct56(tlv::TimestampNameComponent, "TimestampNameComponent", "t");
|
||||
static const DecimalComponentType ct56(tlv::TimestampNameComponent, "TimestampNameComponent"sv, "t"sv);
|
||||
set(tlv::TimestampNameComponent, ct56);
|
||||
static const DecimalComponentType ct58(tlv::SequenceNumNameComponent, "SequenceNumNameComponent", "seq");
|
||||
static const DecimalComponentType ct58(tlv::SequenceNumNameComponent, "SequenceNumNameComponent"sv, "seq"sv);
|
||||
set(tlv::SequenceNumNameComponent, ct58);
|
||||
}
|
||||
|
||||
/** \brief Get the global ComponentTypeTable.
|
||||
/**
|
||||
* \brief Get the global ComponentTypeTable.
|
||||
*/
|
||||
inline const ComponentTypeTable&
|
||||
getComponentTypeTable()
|
||||
@@ -411,8 +396,7 @@ getComponentTypeTable()
|
||||
return ctt;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace name
|
||||
} // namespace ndn
|
||||
} // namespace
|
||||
} // namespace ndn::name
|
||||
|
||||
#endif // NDN_CXX_IMPL_NAME_COMPONENT_TYPES_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2021 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).
|
||||
*
|
||||
@@ -40,14 +40,14 @@ enum class PendingInterestOrigin
|
||||
FORWARDER ///< Interest was received from the forwarder via Transport
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, PendingInterestOrigin origin)
|
||||
{
|
||||
switch (origin) {
|
||||
case PendingInterestOrigin::APP:
|
||||
return os << "app";
|
||||
case PendingInterestOrigin::FORWARDER:
|
||||
return os << "forwarder";
|
||||
case PendingInterestOrigin::APP:
|
||||
return os << "app";
|
||||
case PendingInterestOrigin::FORWARDER:
|
||||
return os << "forwarder";
|
||||
}
|
||||
NDN_CXX_UNREACHABLE;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a pending Interest record for an Interest from the forwarder
|
||||
* @brief Construct a pending Interest record for an Interest from the forwarder.
|
||||
*/
|
||||
PendingInterest(shared_ptr<const Interest> interest, Scheduler& scheduler)
|
||||
: m_interest(std::move(interest))
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Record that the Interest has been forwarded to one destination
|
||||
* @brief Record that the Interest has been forwarded to one destination.
|
||||
*
|
||||
* A "destination" could be either a local InterestFilter or the forwarder.
|
||||
*/
|
||||
@@ -110,11 +110,11 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Record an incoming Nack against a forwarded Interest
|
||||
* @return least severe Nack if all destinations where the Interest was forwarded have Nacked;
|
||||
* otherwise, nullopt
|
||||
* @brief Record an incoming Nack against a forwarded Interest.
|
||||
* @return Least severe Nack if all destinations where the Interest was forwarded have Nacked;
|
||||
* otherwise, @c nullopt.
|
||||
*/
|
||||
optional<lp::Nack>
|
||||
std::optional<lp::Nack>
|
||||
recordNack(const lp::Nack& nack)
|
||||
{
|
||||
--m_nNotNacked;
|
||||
@@ -124,7 +124,7 @@ public:
|
||||
m_leastSevereNack = nack;
|
||||
}
|
||||
|
||||
return m_nNotNacked > 0 ? nullopt : m_leastSevereNack;
|
||||
return m_nNotNacked > 0 ? std::nullopt : m_leastSevereNack;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,7 +180,7 @@ private:
|
||||
TimeoutCallback m_timeoutCallback;
|
||||
scheduler::ScopedEventId m_timeoutEvent;
|
||||
int m_nNotNacked = 0; ///< number of Interest destinations that have not Nacked
|
||||
optional<lp::Nack> m_leastSevereNack;
|
||||
std::optional<lp::Nack> m_leastSevereNack;
|
||||
};
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
Loaded 100 of 630 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user