Compare commits
47
Commits
ndn-cxx-0.8.1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ad02f3428 | ||
|
|
6d4a6536fd | ||
|
|
e58bab2e8a | ||
|
|
995c411ae4 | ||
|
|
49e1e87b24 | ||
|
|
2f46d6543e | ||
|
|
550d8c99ab | ||
|
|
e1005da0a2 | ||
|
|
6028418380 | ||
|
|
5686c51b87 | ||
|
|
c996742bad | ||
|
|
90d3a96dc2 | ||
|
|
fffdd62715 | ||
|
|
ce442c4c95 | ||
|
|
ee97139dcd | ||
|
|
03fdfb17a1 | ||
|
|
747cb45c16 | ||
|
|
9404892918 | ||
|
|
382de67df8 | ||
|
|
0af48fb516 | ||
|
|
12b8aaa9f2 | ||
|
|
502c4c3bd6 | ||
|
|
f81de71486 | ||
|
|
67bc114aa8 | ||
|
|
699cca4ba0 | ||
|
|
296c3a185d | ||
|
|
47ce2eed3a | ||
|
|
21b7f1b379 | ||
|
|
581dd52b0d | ||
|
|
152ef44da9 | ||
|
|
3fdb02f62e | ||
|
|
a3651646a9 | ||
|
|
23483c76d5 | ||
|
|
0910343957 | ||
|
|
187e9f99b2 | ||
|
|
eb87c28200 | ||
|
|
869d1a3c36 | ||
|
|
05ec0be21b | ||
|
|
f6b458930f | ||
|
|
a2fbc35f12 | ||
|
|
fcd3e44028 | ||
|
|
762548b15e | ||
|
|
02ed332ddd | ||
|
|
d09d52bdfa | ||
|
|
ae39daf4de | ||
|
|
a90b2cf762 | ||
|
|
535bd33223 |
No files matched your search
@@ -3,63 +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 }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04]
|
||||
compiler: [g++-7, g++-8, g++-9, g++-10,
|
||||
clang++-7, clang++-8, clang++-9, clang++-10, clang++-11, clang++-12]
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
compiler: g++-11
|
||||
- os: ubuntu-22.04
|
||||
compiler: g++-12
|
||||
- os: ubuntu-22.04
|
||||
compiler: clang++-13
|
||||
- os: ubuntu-22.04
|
||||
compiler: clang++-14
|
||||
env:
|
||||
CXX: ${{ matrix.compiler }}
|
||||
steps:
|
||||
- name: Install C++ compiler
|
||||
run: |
|
||||
sudo apt-get -qy install ${CXX/clang++/clang}
|
||||
${CXX} --version
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Build and test
|
||||
run: ./.jenkins
|
||||
|
||||
macos:
|
||||
name: Xcode ${{ matrix.xcode }} on ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-11]
|
||||
xcode: ['12.4', '12.5', '13.2']
|
||||
include:
|
||||
- os: macos-12
|
||||
xcode: '13.4'
|
||||
- os: macos-12
|
||||
xcode: '14.2'
|
||||
steps:
|
||||
- name: Set up Xcode
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: ${{ matrix.xcode }}
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- 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
-28
@@ -1,35 +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:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
env:
|
||||
JOB_NAME: Docs
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
find .jenkins.d/ -type f -name '[1-9]*.sh' -exec chmod -x '{}' +
|
||||
./.jenkins
|
||||
- name: Build documentation
|
||||
run: |
|
||||
pybindir=$(python3 -c 'import sysconfig; print(sysconfig.get_path("scripts", "posix_user"))')
|
||||
export PATH="${pybindir}${PATH:+:}${PATH}"
|
||||
./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
|
||||
@@ -32,6 +32,9 @@ if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
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
|
||||
|
||||
|
||||
@@ -22,9 +22,5 @@ set -x
|
||||
# Prepare environment
|
||||
rm -rf ~/.ndn
|
||||
|
||||
if [[ $ID == macos && ${VERSION_ID%%.*} -lt 11 ]]; then
|
||||
security unlock-keychain -p named-data
|
||||
fi
|
||||
|
||||
# Run unit tests
|
||||
./build/unit-tests
|
||||
@@ -16,7 +16,7 @@ if [[ $ID_LIKE == *fedora* ]]; then
|
||||
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
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -18,19 +20,22 @@ def configure(conf):
|
||||
if cxx == 'gcc':
|
||||
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.')
|
||||
'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':
|
||||
if ccver < (10, 0, 0):
|
||||
errmsg = ('The version of Xcode you are using is too old.\n'
|
||||
'The minimum supported Xcode version is 11.3.')
|
||||
elif ccver < (11, 0, 0):
|
||||
warnmsg = ('Using a version of Xcode older than 11.3 is not '
|
||||
'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 < (6, 0, 0):
|
||||
elif ccver < (7, 0, 0):
|
||||
errmsg = ('The version of clang you are using is too old.\n'
|
||||
'The minimum supported clang version is 6.0.')
|
||||
'The minimum supported clang version is 7.0.')
|
||||
conf.flags = ClangFlags()
|
||||
else:
|
||||
warnmsg = f'{cxx} compiler is unsupported'
|
||||
@@ -45,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)
|
||||
@@ -53,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
|
||||
@@ -75,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
|
||||
@@ -94,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
|
||||
@@ -114,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"""
|
||||
@@ -130,94 +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']
|
||||
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',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wpedantic',
|
||||
'-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',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wpedantic',
|
||||
'-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',
|
||||
]
|
||||
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',
|
||||
]
|
||||
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
|
||||
brewdir = '/opt/homebrew' if platform.machine() == 'arm64' else '/usr/local'
|
||||
flags['CXXFLAGS'] += [['-isystem', f'{brewdir}/include'], # for Homebrew
|
||||
['-isystem', '/opt/local/include']] # for MacPorts
|
||||
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
|
||||
]
|
||||
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
|
||||
]
|
||||
flags = super().getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
return flags
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
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>
|
||||
|
||||
@@ -9,18 +9,12 @@ ndn-cxx relies on third-party software, licensed under the following licenses:
|
||||
- OpenSSL is licensed under the
|
||||
[Apache License 2.0](https://www.openssl.org/source/license.html)
|
||||
|
||||
- optional-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/optional-lite/blob/master/LICENSE.txt)
|
||||
|
||||
- scope-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/scope-lite/blob/master/LICENSE.txt)
|
||||
|
||||
- span-lite by Martin Moene is licensed under the
|
||||
[Boost Software License 1.0](https://github.com/martinmoene/span-lite/blob/master/LICENSE.txt)
|
||||
|
||||
- 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
|
||||
|
||||
+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,6 +1,6 @@
|
||||
<div align="center">
|
||||
|
||||
[<img alt height="70" src="docs/named_data_theme/static/ndn-logo.svg"/>](https://named-data.net/)
|
||||
[<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
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
[](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:
|
||||
|
||||
@@ -30,21 +30,22 @@ used by the following projects:
|
||||
|
||||
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.
|
||||
+14
-12
@@ -7,18 +7,21 @@ Supported platforms
|
||||
ndn-cxx is built against a continuous integration system and has been tested on the
|
||||
following platforms:
|
||||
|
||||
- Ubuntu 18.04 / 20.04 / 22.04
|
||||
- Debian 11
|
||||
- Ubuntu 20.04 (focal)
|
||||
- Ubuntu 22.04 (jammy)
|
||||
- Debian 11 (bullseye)
|
||||
- Debian 12 (bookworm)
|
||||
- CentOS Stream 9
|
||||
- macOS 10.15 / 11 / 12 / 13
|
||||
- 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:
|
||||
|
||||
- Any other recent version of Ubuntu not listed above
|
||||
- Fedora >= 33
|
||||
- Alpine >= 3.12
|
||||
- Fedora >= 29
|
||||
- Gentoo Linux
|
||||
- Raspberry Pi OS (formerly Raspbian) >= 2019-06-20
|
||||
- Any version of Raspberry Pi OS based on Debian 11 (bullseye) or later
|
||||
- macOS 10.15
|
||||
- FreeBSD >= 12.2
|
||||
|
||||
Prerequisites
|
||||
@@ -27,11 +30,11 @@ Prerequisites
|
||||
Required
|
||||
~~~~~~~~
|
||||
|
||||
- GCC >= 7.4 or clang >= 6.0 (if you are on Linux or FreeBSD)
|
||||
- Xcode >= 11.3 or corresponding version of Command Line Tools (if you are on macOS)
|
||||
- Python >= 3.6
|
||||
- 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.65.1
|
||||
- Boost >= 1.71.0
|
||||
- OpenSSL >= 1.1.1
|
||||
- SQLite 3.x
|
||||
|
||||
@@ -60,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::
|
||||
|
||||
|
||||
+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.
|
||||
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import sys
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
project = 'ndn-cxx: NDN C++ library with eXperimental eXtensions'
|
||||
copyright = 'Copyright © 2013-2022 Regents of the University of California.'
|
||||
copyright = 'Copyright © 2013-2023 Regents of the University of California.'
|
||||
author = 'Named Data Networking Project'
|
||||
|
||||
# The short X.Y version.
|
||||
|
||||
+2
-40
@@ -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
|
||||
@@ -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.
|
||||
|
||||
+8
-8
@@ -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
|
||||
----------------
|
||||
@@ -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
|
||||
|
||||
+3
-3
@@ -19,7 +19,7 @@ ndn-cxx: NDN C++ library with eXperimental eXtensions
|
||||
release-notes
|
||||
releases
|
||||
|
||||
**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:
|
||||
|
||||
@@ -51,7 +51,7 @@ Documentation
|
||||
For developers
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
- `NDN Software Contributor's Guide <https://github.com/named-data/.github/blob/master/CONTRIBUTING.md>`__
|
||||
- `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`
|
||||
@@ -65,7 +65,7 @@ For developers
|
||||
Issues
|
||||
------
|
||||
|
||||
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>`__.
|
||||
|
||||
License
|
||||
|
||||
@@ -32,7 +32,7 @@ $mathjax
|
||||
|
||||
<!--top menu-->
|
||||
<div class="nine columns" id="menu_container" >
|
||||
<h1><a href="https://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-->
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -113,7 +113,7 @@ Deprecated
|
||||
``security::v1::PublicKey``, ``security::v1::Certificate``, ``security::v1::IdentityCertificate``,
|
||||
``security::v1::CertificateExtension``, ``security::v1::CertificateSubjectDescription`` instead.
|
||||
The next release will feature `a new version of the NDN Certificate format
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/certificate.html>`__.
|
||||
<https://docs.named-data.net/NDN-packet-spec/0.3/certificate.html>`__.
|
||||
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
@@ -16,7 +16,7 @@ New features
|
||||
- Add version 2 of the security framework in ``security::v2`` namespace
|
||||
|
||||
* `NDN Certificate Format version 2.0
|
||||
<https://named-data.net/doc/NDN-packet-spec/0.3/certificate.html>`__ (:issue:`3103`)
|
||||
<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`)
|
||||
@@ -63,27 +63,27 @@ Improvements and bug fixes
|
||||
Deprecated
|
||||
^^^^^^^^^^
|
||||
|
||||
- Old security framework. All old security framework classes are moved to
|
||||
- Old security framework. All old security framework classes are moved to the
|
||||
``ndn::security::v1`` namespace in this release and will be removed in the next release.
|
||||
|
||||
* ``v1::KeyChain``, use :ndn-cxx:`v2::KeyChain` instead
|
||||
* ``v1::KeyChain``; use ``v2::KeyChain`` instead.
|
||||
|
||||
* ``v1::Validator`` interface and all implementations of this interface (``ValidatorRegex``,
|
||||
``ValidatorConfig``, ``ValidatorNull``). Use :ndn-cxx:`v2::Validator` and the
|
||||
corresponding implementations of :ndn-cxx:`ValidationPolicy` interfaces (will be introduced
|
||||
before 0.6.0 release).
|
||||
``ValidatorConfig``, ``ValidatorNull``). Use ``v2::Validator`` and the corresponding
|
||||
implementations of :ndn-cxx:`ValidationPolicy` interfaces (will be introduced before
|
||||
the 0.6.0 release).
|
||||
|
||||
* ``v1::SecPublicInfo`` and its implementation (``SecPublicInfoSqlite``), ``SecTpm`` and its
|
||||
implementations (``SecTpmFile``, ``SecTpmOsx``). These classes are internal implementation
|
||||
and not intended to be used without ``v1::KeyChain``. :ndn-cxx:`v2::KeyChain` internally
|
||||
uses the newly introduced :ndn-cxx:`Pib` and :ndn-cxx:`Tpm` interfaces with their
|
||||
corresponding implementations.
|
||||
and not intended to be used without ``v1::KeyChain``. ``v2::KeyChain`` internally uses
|
||||
the newly introduced :ndn-cxx:`Pib` and :ndn-cxx:`Tpm` interfaces with their corresponding
|
||||
implementations.
|
||||
|
||||
* ``v1::Certificate``, ``v1::IdentityCertificate``, ``v1::CertificateExtension``,
|
||||
``v1::CertificateSubjectDescription``, use :ndn-cxx:`v2::Certificate` and
|
||||
:ndn-cxx:`AdditionalDescription`
|
||||
``v1::CertificateSubjectDescription``; use ``v2::Certificate`` and ``AdditionalDescription``
|
||||
instead.
|
||||
|
||||
* ``v1::SecuredBag``, use ``v2::SafeBag`` instead
|
||||
* ``v1::SecuredBag``; use :ndn-cxx:`SafeBag` instead.
|
||||
|
||||
- Constant ``io::BASE_64``, use ``io::BASE64`` instead (:issue:`3741`)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ New features
|
||||
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://named-data.net/doc/NDN-packet-spec/0.3/certificate.html>`__.
|
||||
`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`)
|
||||
@@ -102,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`)
|
||||
|
||||
|
||||
@@ -7,7 +7,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`)
|
||||
|
||||
* Stop using ``ChildSelector`` in ``NotificationSubscriber`` (:issue:`4664`)
|
||||
|
||||
|
||||
@@ -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`)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -12,7 +12,7 @@ Additionally, this release drops support for CentOS 7 and adds support for CentO
|
||||
New features
|
||||
^^^^^^^^^^^^
|
||||
|
||||
- `Signed Interests <https://named-data.net/doc/NDN-packet-spec/0.3/signed-interest.html>`__
|
||||
- `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 :ndn-cxx:`SegmentFetcher` and a corresponding signal that is emitted after
|
||||
|
||||
@@ -32,7 +32,7 @@ Important changes and new features
|
||||
(:issue:`5112`)
|
||||
|
||||
- NFD management commands sent by :ndn-cxx:`nfd::Controller` now use the `new signed Interest
|
||||
format <https://named-data.net/doc/NDN-packet-spec/0.3/signed-interest.html>`__ (:issue:`4804`)
|
||||
format <https://docs.named-data.net/NDN-packet-spec/0.3/signed-interest.html>`__ (:issue:`4804`)
|
||||
|
||||
Improvements and bug fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
+21
-21
@@ -10,37 +10,37 @@ All ndn-cxx Releases
|
||||
release-notes/*
|
||||
|
||||
* **ndn-cxx version 0.8.1**
|
||||
(:doc:`Release Notes <release-notes/release-notes-0.8.1>`, `Documentation <https://named-data.net/doc/ndn-cxx/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>`__)
|
||||
@@ -48,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>`__)
|
||||
@@ -138,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,7 @@ 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. For this purpose, we define the **SafeBag** format, which contains
|
||||
an `NDN certificate <https://named-data.net/doc/NDN-packet-spec/0.3/certificate.html>`__ and the
|
||||
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.
|
||||
|
||||
|
||||
@@ -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,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).
|
||||
*
|
||||
@@ -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`)
|
||||
@@ -52,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.
|
||||
@@ -100,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{m_ioService};
|
||||
Scheduler m_scheduler{m_ioService};
|
||||
// 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
|
||||
|
||||
+12
-13
@@ -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).
|
||||
*
|
||||
@@ -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(make_span(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',
|
||||
|
||||
+79
-15
@@ -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())) {
|
||||
@@ -268,11 +302,19 @@ Data::setContent(span<const uint8_t> value)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Data&
|
||||
Data::setContent(std::string_view value)
|
||||
{
|
||||
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));
|
||||
@@ -283,8 +325,10 @@ Data::setContent(ConstBufferPtr value)
|
||||
Data&
|
||||
Data::unsetContent()
|
||||
{
|
||||
m_content = {};
|
||||
resetWire();
|
||||
if (m_content.isValid()) {
|
||||
m_content = {};
|
||||
resetWire();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -307,8 +351,8 @@ Data::setSignatureValue(span<const uint8_t> value)
|
||||
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));
|
||||
@@ -330,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)
|
||||
{
|
||||
@@ -351,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));
|
||||
@@ -387,3 +450,4 @@ operator<<(std::ostream& os, const Data& data)
|
||||
}
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
+73
-29
@@ -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).
|
||||
*
|
||||
@@ -33,7 +33,7 @@ namespace ndn {
|
||||
|
||||
/**
|
||||
* @brief Represents a %Data packet.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/data.html
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/data.html
|
||||
*/
|
||||
class Data : public PacketBase, public std::enable_shared_from_this<Data>
|
||||
{
|
||||
@@ -95,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
|
||||
@@ -114,16 +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 the data name.
|
||||
* @brief Get the %Data name.
|
||||
*/
|
||||
const Name&
|
||||
getName() const noexcept
|
||||
@@ -132,7 +136,7 @@ public: // Data fields
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the data name.
|
||||
* @brief Set the %Data name.
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
*/
|
||||
Data&
|
||||
@@ -201,14 +205,25 @@ public: // Data fields
|
||||
Data&
|
||||
setContent(span<const uint8_t> value);
|
||||
|
||||
/**
|
||||
* @brief Set `Content` by copying from a string.
|
||||
* @param value string with the TLV-VALUE of the content
|
||||
* @return A reference to this Data, to allow chaining.
|
||||
*/
|
||||
Data&
|
||||
setContent(std::string_view value);
|
||||
|
||||
/**
|
||||
* @brief Set `Content` from a shared buffer.
|
||||
* @param value buffer with the TLV-VALUE of the content; must not be nullptr
|
||||
* @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.
|
||||
@@ -226,14 +241,15 @@ public: // Data fields
|
||||
return m_signatureInfo;
|
||||
}
|
||||
|
||||
/** @brief Set the `SignatureInfo` element.
|
||||
/**
|
||||
* @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);
|
||||
@@ -262,7 +278,7 @@ public: // Data fields
|
||||
|
||||
/**
|
||||
* @brief Set `SignatureValue` from a shared buffer.
|
||||
* @param value buffer containing the TLV-VALUE of the SignatureValue; must not be nullptr
|
||||
* @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.
|
||||
@@ -273,13 +289,33 @@ public: // Data fields
|
||||
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
|
||||
@@ -299,14 +335,14 @@ 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
|
||||
/**
|
||||
@@ -322,15 +358,19 @@ public: // SignatureInfo fields
|
||||
/**
|
||||
* @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();
|
||||
@@ -341,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
|
||||
@@ -369,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 {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+18
-15
@@ -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).
|
||||
*
|
||||
@@ -35,24 +35,28 @@ namespace ndn {
|
||||
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 (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
|
||||
/**
|
||||
* \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 a 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
|
||||
@@ -66,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>
|
||||
@@ -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
-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,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,93 +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
|
||||
*/
|
||||
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
|
||||
@@ -394,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
|
||||
|
||||
+44
-38
@@ -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 ----
|
||||
|
||||
@@ -168,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>
|
||||
@@ -195,25 +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()));
|
||||
return {true, Block(b, type, b->begin(), b->end(), std::prev(b->end(), length), b->end())};
|
||||
}
|
||||
|
||||
Block
|
||||
@@ -411,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
|
||||
@@ -480,41 +481,44 @@ Block::operator boost::asio::const_buffer() const
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const Block& lhs, const Block& rhs) noexcept
|
||||
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_bytes(), 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)
|
||||
{
|
||||
@@ -539,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
|
||||
+86
-59
@@ -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,19 +29,19 @@
|
||||
#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;
|
||||
@@ -162,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
|
||||
@@ -172,7 +172,7 @@ 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 Parse Block from an input stream
|
||||
@@ -223,20 +223,30 @@ 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`
|
||||
*/
|
||||
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`
|
||||
*/
|
||||
const_iterator
|
||||
end() const;
|
||||
|
||||
/**
|
||||
* @brief Return a raw pointer to the beginning of the encoded wire
|
||||
* @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 Returns a raw pointer to the beginning of the encoded wire, i.e., the whole TLV.
|
||||
* @pre `hasWire() == true`
|
||||
* @sa value()
|
||||
*/
|
||||
@@ -246,6 +256,7 @@ public: // wire format
|
||||
/**
|
||||
* @deprecated Use data()
|
||||
*/
|
||||
[[deprecated("use data()")]]
|
||||
const uint8_t*
|
||||
wire() const
|
||||
{
|
||||
@@ -253,14 +264,7 @@ public: // wire format
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return 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 the underlying buffer.
|
||||
*/
|
||||
ConstBufferPtr
|
||||
getBuffer() const
|
||||
@@ -270,7 +274,7 @@ public: // wire format
|
||||
|
||||
public: // type and value
|
||||
/**
|
||||
* @brief Return the TLV-TYPE of the Block
|
||||
* @brief Return the TLV-TYPE of the Block.
|
||||
* @note This will return tlv::Invalid if isValid() is false.
|
||||
*/
|
||||
uint32_t
|
||||
@@ -280,7 +284,7 @@ public: // type and value
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
@@ -294,7 +298,7 @@ public: // type and value
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get begin iterator of TLV-VALUE
|
||||
* @brief Get begin iterator of TLV-VALUE.
|
||||
* @pre `hasValue() == true`
|
||||
*/
|
||||
const_iterator
|
||||
@@ -304,7 +308,7 @@ public: // type and value
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get end iterator of TLV-VALUE
|
||||
* @brief Get end iterator of TLV-VALUE.
|
||||
* @pre `hasValue() == true`
|
||||
*/
|
||||
const_iterator
|
||||
@@ -314,7 +318,7 @@ public: // type and value
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the size of TLV-VALUE, i.e., the TLV-LENGTH
|
||||
* @brief Return the size of TLV-VALUE, i.e., the TLV-LENGTH.
|
||||
* @sa size()
|
||||
*/
|
||||
size_t
|
||||
@@ -324,7 +328,7 @@ public: // type and value
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return a read-only view of TLV-VALUE as a contiguous range of bytes
|
||||
* @brief Return a read-only view of TLV-VALUE as a contiguous range of bytes.
|
||||
*/
|
||||
span<const uint8_t>
|
||||
value_bytes() const noexcept
|
||||
@@ -336,14 +340,14 @@ public: // type and value
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return a raw pointer to the beginning of TLV-VALUE
|
||||
* @brief Return a raw pointer to the beginning of TLV-VALUE.
|
||||
* @sa value_bytes(), data()
|
||||
*/
|
||||
const uint8_t*
|
||||
value() const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Return a new Block constructed from the TLV-VALUE of this Block
|
||||
* @brief Return a new Block constructed from the TLV-VALUE of this Block.
|
||||
* @pre `value_size() > 0`
|
||||
*/
|
||||
Block
|
||||
@@ -462,23 +466,66 @@ public: // misc
|
||||
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
|
||||
*
|
||||
@@ -510,19 +557,6 @@ protected:
|
||||
* 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
|
||||
@@ -531,17 +565,8 @@ Block::Block(Block&&) noexcept = default;
|
||||
inline Block&
|
||||
Block::operator=(Block&&) noexcept = default;
|
||||
|
||||
/**
|
||||
* @brief Compare whether two Blocks have the same TLV-TYPE, TLV-LENGTH, and TLV-VALUE.
|
||||
*/
|
||||
bool
|
||||
operator==(const Block& lhs, const Block& rhs) noexcept;
|
||||
|
||||
inline bool
|
||||
operator!=(const Block& lhs, const Block& rhs) noexcept
|
||||
{
|
||||
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.
|
||||
@@ -559,6 +584,8 @@ operator!=(const Block& lhs, const Block& rhs) noexcept
|
||||
Block
|
||||
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-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,5 +199,4 @@ Encoder::appendNonNegativeInteger(uint64_t varNumber)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace encoding
|
||||
} // namespace ndn
|
||||
} // namespace ndn::encoding
|
||||
@@ -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.
|
||||
@@ -65,28 +66,28 @@ 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/0.3/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/0.3/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/0.3/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/0.3/tlv.html
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/tlv.html
|
||||
*/
|
||||
size_t
|
||||
appendNonNegativeInteger(uint64_t integer);
|
||||
@@ -251,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);
|
||||
@@ -266,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);
|
||||
@@ -276,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,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.
|
||||
@@ -112,7 +111,6 @@ public: // common interface between Encoder and Estimator
|
||||
}
|
||||
};
|
||||
|
||||
} // 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-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).
|
||||
*
|
||||
@@ -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
|
||||
*/
|
||||
@@ -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-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).
|
||||
*
|
||||
@@ -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))
|
||||
@@ -81,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
|
||||
+72
-151
@@ -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).
|
||||
*
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <ostream>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
@@ -38,7 +38,7 @@ 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 Contains constants and low-level functions related to the NDN packet format.
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief TLV-TYPE numbers defined in NDN Packet Format v0.3.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/types.html
|
||||
* @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 {
|
||||
@@ -85,6 +85,10 @@ enum : uint32_t {
|
||||
Nonce = 10,
|
||||
InterestLifetime = 12,
|
||||
HopLimit = 34,
|
||||
ServiceClass = 129,
|
||||
DownstreamRate = 130,
|
||||
TargetRate = 131,
|
||||
Dsz = 132,
|
||||
ApplicationParameters = 36,
|
||||
InterestSignatureInfo = 44,
|
||||
InterestSignatureValue = 46,
|
||||
@@ -121,7 +125,7 @@ enum : uint32_t {
|
||||
|
||||
/**
|
||||
* @brief SignatureType values.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/signature.html#signaturetype
|
||||
* @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 {
|
||||
@@ -138,7 +142,7 @@ operator<<(std::ostream& os, SignatureTypeValue st);
|
||||
|
||||
/**
|
||||
* @brief ContentType values.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/data.html#contenttype
|
||||
* @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 {
|
||||
@@ -156,7 +160,7 @@ 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) noexcept
|
||||
@@ -168,68 +172,68 @@ isCriticalType(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 [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;
|
||||
|
||||
/**
|
||||
@@ -243,23 +247,23 @@ 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;
|
||||
|
||||
/**
|
||||
@@ -270,48 +274,35 @@ 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;
|
||||
@@ -344,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)
|
||||
@@ -386,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;
|
||||
@@ -406,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);
|
||||
@@ -442,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"));
|
||||
}
|
||||
@@ -494,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
|
||||
|
||||
+76
-80
@@ -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,49 +248,52 @@ 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->getState() != Transport::State::CLOSED)
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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);
|
||||
}
|
||||
})
|
||||
|
||||
+78
-75
@@ -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).
|
||||
*
|
||||
@@ -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,35 +184,35 @@ 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();
|
||||
@@ -228,8 +226,8 @@ public: // consumer
|
||||
* @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,
|
||||
@@ -343,61 +341,62 @@ public: // producer
|
||||
|
||||
/**
|
||||
* @brief Publish a Data packet.
|
||||
* @param data the Data; a copy will be made, so that the caller is not required to
|
||||
* maintain the argument unchanged
|
||||
* @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
|
||||
* @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;
|
||||
|
||||
|
||||
@@ -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).
|
||||
*
|
||||
@@ -28,9 +28,12 @@
|
||||
#include "ndn-cxx/detail/common.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>
|
||||
@@ -42,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>
|
||||
@@ -51,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
|
||||
+34
-29
@@ -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);
|
||||
}
|
||||
});
|
||||
@@ -154,17 +158,17 @@ public: // consumer
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
@@ -195,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);
|
||||
}
|
||||
});
|
||||
@@ -234,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;
|
||||
}
|
||||
@@ -255,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();
|
||||
@@ -292,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);
|
||||
}
|
||||
});
|
||||
@@ -305,7 +309,7 @@ public: // IO routine
|
||||
ensureConnected(bool wantResume)
|
||||
{
|
||||
if (m_face.m_transport->getState() == Transport::State::CLOSED) {
|
||||
m_face.m_transport->connect(m_face.getIoService(),
|
||||
m_face.m_transport->connect(m_face.getIoContext(),
|
||||
[this] (const Block& wire) { m_face.onReceiveElement(wire); });
|
||||
}
|
||||
|
||||
@@ -317,7 +321,7 @@ public: // IO routine
|
||||
void
|
||||
shutdown()
|
||||
{
|
||||
m_ioServiceWork.reset();
|
||||
m_workGuard.reset();
|
||||
m_pendingInterestTable.clear();
|
||||
m_registeredPrefixTable.clear();
|
||||
}
|
||||
@@ -416,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-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 ndn::name {
|
||||
namespace {
|
||||
|
||||
/** \brief Declare rules for a NameComponent type.
|
||||
/**
|
||||
* \brief Declare rules for a NameComponent type.
|
||||
*/
|
||||
class ComponentType : noncopyable
|
||||
{
|
||||
@@ -43,17 +43,19 @@ 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
|
||||
@@ -61,7 +63,8 @@ public:
|
||||
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
|
||||
@@ -149,14 +155,15 @@ protected:
|
||||
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
|
||||
{
|
||||
@@ -168,13 +175,15 @@ 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)
|
||||
@@ -186,16 +195,15 @@ public:
|
||||
{
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
std::tuple<bool, Component>
|
||||
getSuccessor(const Component& comp) const final
|
||||
{
|
||||
bool isExtended = false;
|
||||
Block successor;
|
||||
std::tie(isExtended, successor) = getSuccessorImpl(comp);
|
||||
auto [isExtended, successor] = getSuccessorImpl(comp);
|
||||
return {isExtended, isExtended ? comp : Component(successor)};
|
||||
}
|
||||
|
||||
@@ -206,21 +214,21 @@ 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 {m_type, std::move(value)};
|
||||
}
|
||||
@@ -234,17 +242,19 @@ 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 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)
|
||||
@@ -256,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);
|
||||
}
|
||||
@@ -294,8 +304,8 @@ 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;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -322,13 +332,12 @@ public:
|
||||
* \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:
|
||||
@@ -336,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;
|
||||
}
|
||||
}
|
||||
@@ -344,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
|
||||
@@ -353,10 +362,10 @@ ComponentTypeTable::ComponentTypeTable()
|
||||
m_table.fill(nullptr);
|
||||
|
||||
static const Sha256ComponentType ct1(tlv::ImplicitSha256DigestComponent,
|
||||
"ImplicitSha256DigestComponent", "sha256digest");
|
||||
"ImplicitSha256DigestComponent"sv, "sha256digest"sv);
|
||||
set(tlv::ImplicitSha256DigestComponent, ct1);
|
||||
static const Sha256ComponentType ct2(tlv::ParametersSha256DigestComponent,
|
||||
"ParametersSha256DigestComponent", "params-sha256");
|
||||
"ParametersSha256DigestComponent"sv, "params-sha256"sv);
|
||||
set(tlv::ParametersSha256DigestComponent, ct2);
|
||||
|
||||
static const GenericNameComponentType ct8;
|
||||
@@ -365,15 +374,15 @@ ComponentTypeTable::ComponentTypeTable()
|
||||
static const ComponentType ct32;
|
||||
set(tlv::KeywordNameComponent, ct32);
|
||||
|
||||
static const DecimalComponentType ct50(tlv::SegmentNameComponent, "SegmentNameComponent", "seg");
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -388,7 +397,6 @@ getComponentTypeTable()
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace name
|
||||
} // namespace ndn
|
||||
} // 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-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).
|
||||
*
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
* @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
|
||||
|
||||
@@ -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).
|
||||
*
|
||||
@@ -23,12 +23,11 @@
|
||||
#define NDN_CXX_IMPL_RECORD_CONTAINER_HPP
|
||||
|
||||
#include "ndn-cxx/detail/common.hpp"
|
||||
#include "ndn-cxx/util/signal.hpp"
|
||||
#include "ndn-cxx/util/signal/signal.hpp"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace ndn {
|
||||
namespace detail {
|
||||
namespace ndn::detail {
|
||||
|
||||
using RecordId = uint64_t;
|
||||
|
||||
@@ -77,30 +76,30 @@ public:
|
||||
using Record = T;
|
||||
using Container = std::map<RecordId, Record>;
|
||||
|
||||
/** \brief Retrieve record by ID.
|
||||
/**
|
||||
* \brief Retrieve record by ID.
|
||||
*/
|
||||
Record*
|
||||
get(RecordId id)
|
||||
{
|
||||
auto i = m_container.find(id);
|
||||
if (i == m_container.end()) {
|
||||
return nullptr;
|
||||
if (auto it = m_container.find(id); it != m_container.end()) {
|
||||
return &it->second;
|
||||
}
|
||||
return &i->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/** \brief Insert a record with given ID.
|
||||
/**
|
||||
* \brief Insert a record with given ID.
|
||||
*/
|
||||
template<typename ...TArgs>
|
||||
template<typename... TArgs>
|
||||
Record&
|
||||
put(RecordId id, TArgs&&... args)
|
||||
{
|
||||
BOOST_ASSERT(id != 0);
|
||||
auto it = m_container.emplace(std::piecewise_construct, std::forward_as_tuple(id),
|
||||
std::forward_as_tuple(std::forward<decltype(args)>(args)...));
|
||||
BOOST_ASSERT(it.second);
|
||||
auto [it, isNew] = m_container.try_emplace(id, std::forward<decltype(args)>(args)...);
|
||||
BOOST_VERIFY(isNew);
|
||||
|
||||
Record& record = it.first->second;
|
||||
Record& record = it->second;
|
||||
record.m_container = this;
|
||||
record.m_id = id;
|
||||
return record;
|
||||
@@ -112,9 +111,10 @@ public:
|
||||
return ++m_lastId;
|
||||
}
|
||||
|
||||
/** \brief Insert a record with newly assigned ID.
|
||||
/**
|
||||
* \brief Insert a record with newly assigned ID.
|
||||
*/
|
||||
template<typename ...TArgs>
|
||||
template<typename... TArgs>
|
||||
Record&
|
||||
insert(TArgs&&... args)
|
||||
{
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
NDN_CXX_NODISCARD bool
|
||||
[[nodiscard]] bool
|
||||
empty() const noexcept
|
||||
{
|
||||
return m_container.empty();
|
||||
@@ -188,14 +188,13 @@ public:
|
||||
public:
|
||||
/** \brief Signals when container becomes empty
|
||||
*/
|
||||
util::Signal<RecordContainer<T>> onEmpty;
|
||||
signal::Signal<RecordContainer<T>> onEmpty;
|
||||
|
||||
private:
|
||||
Container m_container;
|
||||
std::atomic<RecordId> m_lastId{0};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace ndn
|
||||
} // namespace ndn::detail
|
||||
|
||||
#endif // NDN_CXX_IMPL_RECORD_CONTAINER_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -28,8 +28,8 @@ InMemoryStorageFifo::InMemoryStorageFifo(size_t limit)
|
||||
{
|
||||
}
|
||||
|
||||
InMemoryStorageFifo::InMemoryStorageFifo(boost::asio::io_service& ioService, size_t limit)
|
||||
: InMemoryStorage(ioService, limit)
|
||||
InMemoryStorageFifo::InMemoryStorageFifo(boost::asio::io_context& ioCtx, size_t limit)
|
||||
: InMemoryStorage(ioCtx, limit)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ bool
|
||||
InMemoryStorageFifo::evictItem()
|
||||
{
|
||||
if (!m_cleanupIndex.get<byArrival>().empty()) {
|
||||
CleanupIndex::index<byArrival>::type::iterator it = m_cleanupIndex.get<byArrival>().begin();
|
||||
auto it = m_cleanupIndex.get<byArrival>().begin();
|
||||
eraseImpl((*it)->getFullName());
|
||||
m_cleanupIndex.get<byArrival>().erase(it);
|
||||
return true;
|
||||
@@ -56,7 +56,7 @@ InMemoryStorageFifo::evictItem()
|
||||
void
|
||||
InMemoryStorageFifo::beforeErase(InMemoryStorageEntry* entry)
|
||||
{
|
||||
CleanupIndex::index<byEntity>::type::iterator it = m_cleanupIndex.get<byEntity>().find(entry);
|
||||
auto it = m_cleanupIndex.get<byEntity>().find(entry);
|
||||
if (it != m_cleanupIndex.get<byEntity>().end())
|
||||
m_cleanupIndex.get<byEntity>().erase(it);
|
||||
}
|
||||
|
||||
@@ -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,7 +30,8 @@
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** @brief Provides in-memory storage employing First-In-First-Out (FIFO) replacement policy.
|
||||
/**
|
||||
* @brief Provides in-memory storage employing First-In-First-Out (FIFO) replacement policy.
|
||||
*/
|
||||
class InMemoryStorageFifo : public InMemoryStorage
|
||||
{
|
||||
@@ -39,7 +40,7 @@ public:
|
||||
InMemoryStorageFifo(size_t limit = 16);
|
||||
|
||||
explicit
|
||||
InMemoryStorageFifo(boost::asio::io_service& ioService, size_t limit = 16);
|
||||
InMemoryStorageFifo(boost::asio::io_context& ioCtx, size_t limit = 16);
|
||||
|
||||
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
|
||||
/** @brief Removes one Data packet from in-memory storage based on FIFO
|
||||
@@ -64,23 +65,20 @@ private:
|
||||
class byArrival;
|
||||
class byEntity;
|
||||
|
||||
typedef boost::multi_index_container<
|
||||
using CleanupIndex = boost::multi_index_container<
|
||||
InMemoryStorageEntry*,
|
||||
boost::multi_index::indexed_by<
|
||||
|
||||
// by Entry itself
|
||||
boost::multi_index::hashed_unique<
|
||||
boost::multi_index::tag<byEntity>,
|
||||
boost::multi_index::identity<InMemoryStorageEntry*>
|
||||
>,
|
||||
|
||||
// by arrival (FIFO)
|
||||
boost::multi_index::sequenced<
|
||||
boost::multi_index::tag<byArrival>
|
||||
>
|
||||
|
||||
>
|
||||
> CleanupIndex;
|
||||
>;
|
||||
|
||||
CleanupIndex m_cleanupIndex;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -28,8 +28,8 @@ InMemoryStorageLfu::InMemoryStorageLfu(size_t limit)
|
||||
{
|
||||
}
|
||||
|
||||
InMemoryStorageLfu::InMemoryStorageLfu(boost::asio::io_service& ioService, size_t limit)
|
||||
: InMemoryStorage(ioService, limit)
|
||||
InMemoryStorageLfu::InMemoryStorageLfu(boost::asio::io_context& ioCtx, size_t limit)
|
||||
: InMemoryStorage(ioCtx, limit)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ bool
|
||||
InMemoryStorageLfu::evictItem()
|
||||
{
|
||||
if (!m_cleanupIndex.get<byFrequency>().empty()) {
|
||||
CleanupIndex::index<byFrequency>::type::iterator it = m_cleanupIndex.get<byFrequency>().begin();
|
||||
auto it = m_cleanupIndex.get<byFrequency>().begin();
|
||||
eraseImpl(((*it).entry)->getFullName());
|
||||
m_cleanupIndex.get<byFrequency>().erase(it);
|
||||
return true;
|
||||
@@ -59,7 +59,7 @@ InMemoryStorageLfu::evictItem()
|
||||
void
|
||||
InMemoryStorageLfu::beforeErase(InMemoryStorageEntry* entry)
|
||||
{
|
||||
CleanupIndex::index<byEntity>::type::iterator it = m_cleanupIndex.get<byEntity>().find(entry);
|
||||
auto it = m_cleanupIndex.get<byEntity>().find(entry);
|
||||
if (it != m_cleanupIndex.get<byEntity>().end())
|
||||
m_cleanupIndex.get<byEntity>().erase(it);
|
||||
}
|
||||
@@ -67,7 +67,7 @@ InMemoryStorageLfu::beforeErase(InMemoryStorageEntry* entry)
|
||||
void
|
||||
InMemoryStorageLfu::afterAccess(InMemoryStorageEntry* entry)
|
||||
{
|
||||
CleanupIndex::index<byEntity>::type::iterator it = m_cleanupIndex.get<byEntity>().find(entry);
|
||||
auto it = m_cleanupIndex.get<byEntity>().find(entry);
|
||||
m_cleanupIndex.get<byEntity>().modify(it, &incrementFrequency);
|
||||
}
|
||||
|
||||
|
||||
@@ -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).
|
||||
*
|
||||
@@ -32,9 +32,9 @@
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** @brief Provides an in-memory storage with Least Frequently Used (LFU) replacement policy.
|
||||
* @note The frequency right now is usage count.
|
||||
* @sa https://en.wikipedia.org/w/index.php?title=Least_frequently_used&oldid=604542656
|
||||
/**
|
||||
* @brief Provides an in-memory storage with Least Frequently Used (LFU) replacement policy.
|
||||
* @note The frequency right now is usage count.
|
||||
*/
|
||||
class InMemoryStorageLfu : public InMemoryStorage
|
||||
{
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
InMemoryStorageLfu(size_t limit = 16);
|
||||
|
||||
explicit
|
||||
InMemoryStorageLfu(boost::asio::io_service& ioService, size_t limit = 16);
|
||||
InMemoryStorageLfu(boost::asio::io_context& ioCtx, size_t limit = 16);
|
||||
|
||||
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
|
||||
/** @brief Removes one Data packet from in-memory storage based on LFU, i.e. evict the least
|
||||
@@ -91,25 +91,22 @@ private:
|
||||
class byFrequency;
|
||||
class byEntity;
|
||||
|
||||
typedef boost::multi_index_container<
|
||||
using CleanupIndex = boost::multi_index_container<
|
||||
CleanupEntry,
|
||||
boost::multi_index::indexed_by<
|
||||
|
||||
// by Entry itself
|
||||
boost::multi_index::hashed_unique<
|
||||
boost::multi_index::tag<byEntity>,
|
||||
boost::multi_index::member<CleanupEntry, InMemoryStorageEntry*, &CleanupEntry::entry>
|
||||
>,
|
||||
|
||||
// by frequency (LFU)
|
||||
boost::multi_index::ordered_non_unique<
|
||||
boost::multi_index::tag<byFrequency>,
|
||||
boost::multi_index::member<CleanupEntry, uint64_t, &CleanupEntry::frequency>,
|
||||
std::less<uint64_t>
|
||||
>
|
||||
|
||||
>
|
||||
> CleanupIndex;
|
||||
>;
|
||||
|
||||
CleanupIndex m_cleanupIndex;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -28,9 +28,8 @@ InMemoryStorageLru::InMemoryStorageLru(size_t limit)
|
||||
{
|
||||
}
|
||||
|
||||
InMemoryStorageLru::InMemoryStorageLru(boost::asio::io_service& ioService,
|
||||
size_t limit)
|
||||
: InMemoryStorage(ioService, limit)
|
||||
InMemoryStorageLru::InMemoryStorageLru(boost::asio::io_context& ioCtx, size_t limit)
|
||||
: InMemoryStorage(ioCtx, limit)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -46,7 +45,7 @@ bool
|
||||
InMemoryStorageLru::evictItem()
|
||||
{
|
||||
if (!m_cleanupIndex.get<byUsedTime>().empty()) {
|
||||
CleanupIndex::index<byUsedTime>::type::iterator it = m_cleanupIndex.get<byUsedTime>().begin();
|
||||
auto it = m_cleanupIndex.get<byUsedTime>().begin();
|
||||
eraseImpl((*it)->getFullName());
|
||||
m_cleanupIndex.get<byUsedTime>().erase(it);
|
||||
return true;
|
||||
@@ -58,7 +57,7 @@ InMemoryStorageLru::evictItem()
|
||||
void
|
||||
InMemoryStorageLru::beforeErase(InMemoryStorageEntry* entry)
|
||||
{
|
||||
CleanupIndex::index<byEntity>::type::iterator it = m_cleanupIndex.get<byEntity>().find(entry);
|
||||
auto it = m_cleanupIndex.get<byEntity>().find(entry);
|
||||
if (it != m_cleanupIndex.get<byEntity>().end())
|
||||
m_cleanupIndex.get<byEntity>().erase(it);
|
||||
}
|
||||
|
||||
@@ -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).
|
||||
*
|
||||
@@ -32,7 +32,8 @@
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** @brief Provides in-memory storage employing Least Recently Used (LRU) replacement policy.
|
||||
/**
|
||||
* @brief Provides in-memory storage employing Least Recently Used (LRU) replacement policy.
|
||||
*/
|
||||
class InMemoryStorageLru : public InMemoryStorage
|
||||
{
|
||||
@@ -41,7 +42,7 @@ public:
|
||||
InMemoryStorageLru(size_t limit = 16);
|
||||
|
||||
explicit
|
||||
InMemoryStorageLru(boost::asio::io_service& ioService, size_t limit = 16);
|
||||
InMemoryStorageLru(boost::asio::io_context& ioCtx, size_t limit = 16);
|
||||
|
||||
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
|
||||
/** @brief Removes one Data packet from in-memory storage based on LRU, i.e. evict the least
|
||||
@@ -73,23 +74,20 @@ private:
|
||||
class byUsedTime;
|
||||
class byEntity;
|
||||
|
||||
typedef boost::multi_index_container<
|
||||
using CleanupIndex = boost::multi_index_container<
|
||||
InMemoryStorageEntry*,
|
||||
boost::multi_index::indexed_by<
|
||||
|
||||
// by Entry itself
|
||||
boost::multi_index::hashed_unique<
|
||||
boost::multi_index::tag<byEntity>,
|
||||
boost::multi_index::identity<InMemoryStorageEntry*>
|
||||
>,
|
||||
|
||||
// by last used time (LRU)
|
||||
boost::multi_index::sequenced<
|
||||
boost::multi_index::tag<byUsedTime>
|
||||
>
|
||||
|
||||
>
|
||||
> CleanupIndex;
|
||||
>;
|
||||
|
||||
CleanupIndex m_cleanupIndex;
|
||||
};
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received copies of the GNU General Public License and GNU Lesser
|
||||
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
|
||||
*/
|
||||
|
||||
#include "ndn-cxx/ims/in-memory-storage-persistent.hpp"
|
||||
|
||||
namespace ndn {
|
||||
|
||||
InMemoryStoragePersistent::InMemoryStoragePersistent()
|
||||
: InMemoryStorage()
|
||||
{
|
||||
}
|
||||
|
||||
InMemoryStoragePersistent::InMemoryStoragePersistent(boost::asio::io_service& ioService)
|
||||
: InMemoryStorage(ioService)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
InMemoryStoragePersistent::evictItem()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace ndn
|
||||
@@ -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,26 +26,32 @@
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/** @brief Provides application cache with persistent storage, of which no replacement policy will
|
||||
* be employed. Entries will only be deleted by explicit application control.
|
||||
/**
|
||||
* @brief Provides application cache with persistent storage, of which no replacement policy will
|
||||
* be employed. Entries will only be deleted by explicit application control.
|
||||
*/
|
||||
class InMemoryStoragePersistent : public InMemoryStorage
|
||||
{
|
||||
public:
|
||||
InMemoryStoragePersistent();
|
||||
InMemoryStoragePersistent() = default;
|
||||
|
||||
explicit
|
||||
InMemoryStoragePersistent(boost::asio::io_service& ioService);
|
||||
InMemoryStoragePersistent(boost::asio::io_context& ioCtx)
|
||||
: InMemoryStorage(ioCtx)
|
||||
{
|
||||
}
|
||||
|
||||
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
|
||||
/** @brief Do nothing.
|
||||
/**
|
||||
* @brief Do nothing.
|
||||
*
|
||||
* This storage is persistent, and does not support eviction.
|
||||
*
|
||||
* @return false
|
||||
* This storage is persistent, and thus does not support eviction.
|
||||
*/
|
||||
bool
|
||||
evictItem() override;
|
||||
evictItem() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
@@ -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).
|
||||
*
|
||||
@@ -24,16 +24,8 @@
|
||||
|
||||
namespace ndn {
|
||||
|
||||
const time::milliseconds InMemoryStorage::INFINITE_WINDOW(-1);
|
||||
const time::milliseconds InMemoryStorage::ZERO_WINDOW(0);
|
||||
|
||||
InMemoryStorage::const_iterator::const_iterator(const Data* ptr, const Cache* cache,
|
||||
Cache::index<byFullName>::type::iterator it)
|
||||
: m_ptr(ptr)
|
||||
, m_cache(cache)
|
||||
, m_it(it)
|
||||
{
|
||||
}
|
||||
constexpr size_t MIN_CAPACITY = 16;
|
||||
constexpr time::milliseconds ZERO_WINDOW = 0_ms;
|
||||
|
||||
InMemoryStorage::const_iterator&
|
||||
InMemoryStorage::const_iterator::operator++()
|
||||
@@ -45,42 +37,9 @@ InMemoryStorage::const_iterator::operator++()
|
||||
else {
|
||||
m_ptr = nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
InMemoryStorage::const_iterator
|
||||
InMemoryStorage::const_iterator::operator++(int)
|
||||
{
|
||||
InMemoryStorage::const_iterator i(*this);
|
||||
this->operator++();
|
||||
return i;
|
||||
}
|
||||
|
||||
InMemoryStorage::const_iterator::reference
|
||||
InMemoryStorage::const_iterator::operator*()
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
InMemoryStorage::const_iterator::pointer
|
||||
InMemoryStorage::const_iterator::operator->()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
bool
|
||||
InMemoryStorage::const_iterator::operator==(const const_iterator& rhs)
|
||||
{
|
||||
return m_it == rhs.m_it;
|
||||
}
|
||||
|
||||
bool
|
||||
InMemoryStorage::const_iterator::operator!=(const const_iterator& rhs)
|
||||
{
|
||||
return m_it != rhs.m_it;
|
||||
}
|
||||
|
||||
InMemoryStorage::InMemoryStorage(size_t limit)
|
||||
: m_limit(limit)
|
||||
, m_nPackets(0)
|
||||
@@ -88,11 +47,11 @@ InMemoryStorage::InMemoryStorage(size_t limit)
|
||||
init();
|
||||
}
|
||||
|
||||
InMemoryStorage::InMemoryStorage(boost::asio::io_service& ioService, size_t limit)
|
||||
InMemoryStorage::InMemoryStorage(boost::asio::io_context& ioCtx, size_t limit)
|
||||
: m_limit(limit)
|
||||
, m_nPackets(0)
|
||||
{
|
||||
m_scheduler = make_unique<Scheduler>(ioService);
|
||||
m_scheduler = make_unique<Scheduler>(ioCtx);
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -100,7 +59,7 @@ void
|
||||
InMemoryStorage::init()
|
||||
{
|
||||
// TODO consider a more suitable initial value
|
||||
m_capacity = m_initCapacity;
|
||||
m_capacity = MIN_CAPACITY;
|
||||
|
||||
if (m_limit != std::numeric_limits<size_t>::max() && m_capacity > m_limit) {
|
||||
m_capacity = m_limit;
|
||||
@@ -131,7 +90,7 @@ void
|
||||
InMemoryStorage::setCapacity(size_t capacity)
|
||||
{
|
||||
size_t oldCapacity = m_capacity;
|
||||
m_capacity = std::max(capacity, m_initCapacity);
|
||||
m_capacity = std::max(capacity, MIN_CAPACITY);
|
||||
|
||||
if (size() > m_capacity) {
|
||||
ssize_t nAllowedFailures = size() - m_capacity;
|
||||
@@ -185,7 +144,7 @@ InMemoryStorage::insert(const Data& data, const time::milliseconds& mustBeFreshP
|
||||
m_freeEntries.pop();
|
||||
m_nPackets++;
|
||||
entry->setData(data);
|
||||
if (m_scheduler != nullptr && mustBeFreshProcessingWindow > ZERO_WINDOW) {
|
||||
if (m_scheduler != nullptr && mustBeFreshProcessingWindow >= ZERO_WINDOW) {
|
||||
entry->scheduleMarkStale(*m_scheduler, mustBeFreshProcessingWindow);
|
||||
}
|
||||
m_cache.insert(entry);
|
||||
@@ -367,17 +326,17 @@ InMemoryStorage::end() const
|
||||
}
|
||||
|
||||
void
|
||||
InMemoryStorage::afterInsert(InMemoryStorageEntry* entry)
|
||||
InMemoryStorage::afterInsert(InMemoryStorageEntry*)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
InMemoryStorage::beforeErase(InMemoryStorageEntry* entry)
|
||||
InMemoryStorage::beforeErase(InMemoryStorageEntry*)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
InMemoryStorage::afterAccess(InMemoryStorageEntry* entry)
|
||||
InMemoryStorage::afterAccess(InMemoryStorageEntry*)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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,7 +24,7 @@
|
||||
|
||||
#include "ndn-cxx/ims/in-memory-storage-entry.hpp"
|
||||
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <stack>
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
@@ -44,10 +44,9 @@ public:
|
||||
// multi_index_container to implement storage
|
||||
class byFullName;
|
||||
|
||||
typedef boost::multi_index_container<
|
||||
using Cache = boost::multi_index_container<
|
||||
InMemoryStorageEntry*,
|
||||
boost::multi_index::indexed_by<
|
||||
|
||||
// by Full Name
|
||||
boost::multi_index::ordered_unique<
|
||||
boost::multi_index::tag<byFullName>,
|
||||
@@ -55,43 +54,38 @@ public:
|
||||
&InMemoryStorageEntry::getFullName>,
|
||||
std::less<Name>
|
||||
>
|
||||
|
||||
>
|
||||
> Cache;
|
||||
>;
|
||||
|
||||
/** @brief Represents a self-defined const_iterator for the in-memory storage.
|
||||
*
|
||||
* @note Don't try to instantiate this class directly, use InMemoryStorage::begin() instead.
|
||||
/**
|
||||
* @brief Represents a const_iterator for the in-memory storage.
|
||||
* @note Do not instantiate this class directly, use InMemoryStorage::begin() instead.
|
||||
*/
|
||||
class const_iterator
|
||||
class const_iterator : public boost::forward_iterator_helper<const_iterator, const Data>
|
||||
{
|
||||
public:
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using value_type = const Data;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
|
||||
const_iterator(const Data* ptr, const Cache* cache,
|
||||
Cache::index<byFullName>::type::iterator it);
|
||||
Cache::index<byFullName>::type::iterator it) noexcept
|
||||
: m_ptr(ptr)
|
||||
, m_cache(cache)
|
||||
, m_it(it)
|
||||
{
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const noexcept
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
const_iterator&
|
||||
operator++();
|
||||
|
||||
const_iterator
|
||||
operator++(int);
|
||||
|
||||
reference
|
||||
operator*();
|
||||
|
||||
pointer
|
||||
operator->();
|
||||
|
||||
bool
|
||||
operator==(const const_iterator& rhs);
|
||||
|
||||
bool
|
||||
operator!=(const const_iterator& rhs);
|
||||
friend bool
|
||||
operator==(const const_iterator& lhs, const const_iterator& rhs) noexcept
|
||||
{
|
||||
return lhs.m_it == rhs.m_it;
|
||||
}
|
||||
|
||||
private:
|
||||
const Data* m_ptr;
|
||||
@@ -123,7 +117,7 @@ public:
|
||||
* The InMemoryStorage created through this method will handle MustBeFresh in interest processing
|
||||
*/
|
||||
explicit
|
||||
InMemoryStorage(boost::asio::io_service& ioService,
|
||||
InMemoryStorage(boost::asio::io_context& ioCtx,
|
||||
size_t limit = std::numeric_limits<size_t>::max());
|
||||
|
||||
/** @note Please make sure to implement it to free m_freeEntries and evict
|
||||
@@ -135,8 +129,14 @@ public:
|
||||
/** @brief Inserts a Data packet.
|
||||
*
|
||||
* @param data the packet to insert, must be signed and have wire encoding
|
||||
* @param mustBeFreshProcessingWindow Beyond this time period after the data is inserted, the
|
||||
* data can only be used to answer interest without MustBeFresh selector.
|
||||
* @param mustBeFreshProcessingWindow Beyond this time period, the inserted data can
|
||||
* only be used to answer interest without MustBeFresh. The value of
|
||||
* mustBeFreshProcessingWindow is an application decision and it may or may not
|
||||
* correspond to FreshnessPeriod.
|
||||
*
|
||||
* @note InMemoryStorage does not use the inserted data packet's FreshnessPeriod value.
|
||||
* If the packet needs to be marked "stale" after application-defined period of time,
|
||||
* the application must supply proper @p mustBeFreshProcessingWindow value.
|
||||
*
|
||||
* @note Packets are considered duplicate if the name with implicit digest matches.
|
||||
* The new Data packet with the identical name, but a different payload
|
||||
@@ -325,17 +325,12 @@ private:
|
||||
init();
|
||||
|
||||
public:
|
||||
static const time::milliseconds INFINITE_WINDOW;
|
||||
|
||||
private:
|
||||
static const time::milliseconds ZERO_WINDOW;
|
||||
static constexpr time::milliseconds INFINITE_WINDOW = -1_ms;
|
||||
|
||||
private:
|
||||
Cache m_cache;
|
||||
/// user defined maximum capacity of the in-memory storage in packets
|
||||
size_t m_limit;
|
||||
/// initial capacity, used as minimum capacity
|
||||
const size_t m_initCapacity = 16;
|
||||
/// current capacity of the in-memory storage in packets
|
||||
size_t m_capacity;
|
||||
/// current number of packets in in-memory storage
|
||||
|
||||
@@ -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).
|
||||
*
|
||||
@@ -125,7 +125,7 @@ public:
|
||||
/**
|
||||
* \brief Get whether Interest loopback is allowed.
|
||||
*/
|
||||
NDN_CXX_NODISCARD bool
|
||||
[[nodiscard]] bool
|
||||
allowsLoopback() const noexcept
|
||||
{
|
||||
return m_allowsLoopback;
|
||||
|
||||
+143
-38
@@ -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,19 +29,12 @@
|
||||
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
||||
namespace ndn {
|
||||
|
||||
BOOST_CONCEPT_ASSERT((WireEncodable<Interest>));
|
||||
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Interest>));
|
||||
BOOST_CONCEPT_ASSERT((WireDecodable<Interest>));
|
||||
static_assert(std::is_base_of<tlv::Error, Interest::Error>::value,
|
||||
"Interest::Error must inherit from tlv::Error");
|
||||
|
||||
bool Interest::s_autoCheckParametersDigest = true;
|
||||
|
||||
Interest::Interest(const Name& name, time::milliseconds lifetime)
|
||||
{
|
||||
setName(name);
|
||||
@@ -67,6 +60,9 @@ Interest::wireEncode(EncodingImpl<TAG>& encoder) const
|
||||
// [Nonce]
|
||||
// [InterestLifetime]
|
||||
// [HopLimit]
|
||||
// [Dsz]
|
||||
// [ServiceClass]
|
||||
// [DownstreamRate]
|
||||
// [ApplicationParameters [InterestSignature]]
|
||||
// (elements are encoded in reverse order)
|
||||
|
||||
@@ -88,6 +84,25 @@ Interest::wireEncode(EncodingImpl<TAG>& encoder) const
|
||||
totalLength += prependBlock(encoder, block);
|
||||
}
|
||||
|
||||
// DownstreamRate
|
||||
if (getDownstreamRate()) {
|
||||
uint64_t downstreamRate = *getDownstreamRate();
|
||||
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::DownstreamRate, downstreamRate);
|
||||
// totalLength += encoder.prependByteArrayBlock(tlv::DownstreamRate, reinterpret_cast<uint8_t*>(&downstreamRate), sizeof(downstreamRate));
|
||||
}
|
||||
// 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));
|
||||
}
|
||||
// Dsz
|
||||
if (getDsz()) {
|
||||
uint16_t dsz = *getDsz();
|
||||
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::Dsz, dsz);
|
||||
// totalLength += encoder.prependByteArrayBlock(tlv::Dsz, reinterpret_cast<uint8_t*>(&dsz), sizeof(dsz));
|
||||
}
|
||||
|
||||
// HopLimit
|
||||
if (getHopLimit()) {
|
||||
totalLength += prependBinaryBlock(encoder, tlv::HopLimit, {*m_hopLimit});
|
||||
@@ -163,6 +178,9 @@ Interest::wireDecode(const Block& wire)
|
||||
// [Nonce]
|
||||
// [InterestLifetime]
|
||||
// [HopLimit]
|
||||
// [Dsz]
|
||||
// [ServiceClass]
|
||||
// [DownstreamRate]
|
||||
// [ApplicationParameters [InterestSignature]]
|
||||
|
||||
auto element = m_wire.elements_begin();
|
||||
@@ -186,6 +204,9 @@ Interest::wireDecode(const Block& wire)
|
||||
m_nonce.reset();
|
||||
m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
|
||||
m_hopLimit.reset();
|
||||
m_serviceClass.reset();
|
||||
m_downstreamRate.reset();
|
||||
m_dsz.reset();
|
||||
m_parameters.clear();
|
||||
|
||||
int lastElement = 1; // last recognized element index, in spec order
|
||||
@@ -284,13 +305,50 @@ Interest::wireDecode(const Block& wire)
|
||||
lastElement = 7;
|
||||
break;
|
||||
}
|
||||
case tlv::ApplicationParameters: {
|
||||
case tlv::Dsz: {
|
||||
if (lastElement >= 8) {
|
||||
break; // Dsz is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
if (element->value_size() != 2) {
|
||||
NDN_THROW(Error("Dsz element is malformed"));
|
||||
}
|
||||
uint16_t dsz = 0;
|
||||
std::memcpy(&dsz, element->value(), sizeof(dsz));
|
||||
m_dsz = dsz;
|
||||
lastElement = 8;
|
||||
break;
|
||||
}
|
||||
case tlv::ServiceClass: {
|
||||
if (lastElement >= 9) {
|
||||
break; // ServiceClass is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
if (element->value_size() != 1) {
|
||||
NDN_THROW(Error("ServiceClass element is malformed" + std::to_string(element->value_size())));
|
||||
}
|
||||
m_serviceClass = *element->value();
|
||||
lastElement = 9;
|
||||
break;
|
||||
}
|
||||
case tlv::DownstreamRate: {
|
||||
if (lastElement >= 10) {
|
||||
break; // DownstreamRate is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
uint64_t downstreamRate = 0;
|
||||
if (element->value_size() != 8) {
|
||||
NDN_THROW(Error("DownstreamRate element is malformed"));
|
||||
}
|
||||
std::memcpy(&downstreamRate, element->value(), sizeof(downstreamRate));
|
||||
m_downstreamRate = downstreamRate;
|
||||
lastElement = 10;
|
||||
break;
|
||||
}
|
||||
case tlv::ApplicationParameters: {
|
||||
if (lastElement >= 11) {
|
||||
break; // ApplicationParameters is non-critical, ignore out-of-order appearance
|
||||
}
|
||||
BOOST_ASSERT(!hasApplicationParameters());
|
||||
m_parameters.push_back(*element);
|
||||
lastElement = 8;
|
||||
lastElement = 11;
|
||||
break;
|
||||
}
|
||||
default: { // unrecognized element
|
||||
@@ -326,33 +384,26 @@ Interest::toUri() const
|
||||
bool
|
||||
Interest::matchesData(const Data& data) const
|
||||
{
|
||||
size_t interestNameLength = m_name.size();
|
||||
const Name& dataName = data.getName();
|
||||
size_t fullNameLength = dataName.size() + 1;
|
||||
|
||||
// check Name and CanBePrefix
|
||||
if (interestNameLength == fullNameLength) {
|
||||
if (m_name.size() == fullNameLength) {
|
||||
if (m_name.get(-1).isImplicitSha256Digest()) {
|
||||
if (m_name != data.getFullName()) {
|
||||
return false;
|
||||
}
|
||||
return m_name == data.getFullName();
|
||||
}
|
||||
else {
|
||||
// Interest Name is same length as Data full Name, but last component isn't digest
|
||||
// so there's no possibility of matching
|
||||
// the Interest name has the same length as the Data full name, but the last
|
||||
// component is not a digest, so there is no possibility of matching
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (getCanBePrefix() ? !m_name.isPrefixOf(dataName) : (m_name != dataName)) {
|
||||
return false;
|
||||
else if (m_canBePrefix) {
|
||||
return m_name.isPrefixOf(dataName);
|
||||
}
|
||||
|
||||
// check MustBeFresh
|
||||
if (getMustBeFresh() && data.getFreshnessPeriod() <= 0_ms) {
|
||||
return false;
|
||||
else {
|
||||
return m_name == dataName;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -383,6 +434,26 @@ Interest::setName(const Name& name)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Interest&
|
||||
Interest::setCanBePrefix(bool canBePrefix)
|
||||
{
|
||||
if (canBePrefix != m_canBePrefix) {
|
||||
m_canBePrefix = canBePrefix;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Interest&
|
||||
Interest::setMustBeFresh(bool mustBeFresh)
|
||||
{
|
||||
if (mustBeFresh != m_mustBeFresh) {
|
||||
m_mustBeFresh = mustBeFresh;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Interest&
|
||||
Interest::setForwardingHint(std::vector<Name> value)
|
||||
{
|
||||
@@ -391,7 +462,35 @@ Interest::setForwardingHint(std::vector<Name> value)
|
||||
return *this;
|
||||
}
|
||||
|
||||
static auto
|
||||
const Interest&
|
||||
Interest::setServiceClass(std::optional<uint8_t> serviceClass) const
|
||||
{
|
||||
if (m_serviceClass != serviceClass) {
|
||||
m_serviceClass = serviceClass;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
const Interest&
|
||||
Interest::setDownstreamRate(std::optional<uint64_t> downstreamRate) const
|
||||
{
|
||||
if (m_downstreamRate != downstreamRate) {
|
||||
m_downstreamRate = downstreamRate;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
const Interest&
|
||||
Interest::setDsz(std::optional<uint16_t> dsz) const
|
||||
{
|
||||
if (m_dsz != dsz) {
|
||||
m_dsz = dsz;
|
||||
m_wire.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] static auto
|
||||
generateNonce()
|
||||
{
|
||||
uint32_t r = random::generateWord32();
|
||||
@@ -411,7 +510,7 @@ Interest::getNonce() const
|
||||
}
|
||||
|
||||
Interest&
|
||||
Interest::setNonce(optional<Interest::Nonce> nonce)
|
||||
Interest::setNonce(std::optional<Interest::Nonce> nonce)
|
||||
{
|
||||
if (nonce != m_nonce) {
|
||||
m_nonce = nonce;
|
||||
@@ -448,7 +547,7 @@ Interest::setInterestLifetime(time::milliseconds lifetime)
|
||||
}
|
||||
|
||||
Interest&
|
||||
Interest::setHopLimit(optional<uint8_t> hopLimit)
|
||||
Interest::setHopLimit(std::optional<uint8_t> hopLimit)
|
||||
{
|
||||
if (hopLimit != m_hopLimit) {
|
||||
m_hopLimit = hopLimit;
|
||||
@@ -495,11 +594,17 @@ Interest::setApplicationParameters(span<const uint8_t> value)
|
||||
return setApplicationParametersInternal(makeBinaryBlock(tlv::ApplicationParameters, value));
|
||||
}
|
||||
|
||||
Interest&
|
||||
Interest::setApplicationParameters(std::string_view value)
|
||||
{
|
||||
return setApplicationParametersInternal(makeStringBlock(tlv::ApplicationParameters, value));
|
||||
}
|
||||
|
||||
Interest&
|
||||
Interest::setApplicationParameters(ConstBufferPtr value)
|
||||
{
|
||||
if (value == nullptr) {
|
||||
NDN_THROW(std::invalid_argument("ApplicationParameters buffer cannot be nullptr"));
|
||||
if (!value) {
|
||||
NDN_THROW(std::invalid_argument("ApplicationParameters buffer cannot be null"));
|
||||
}
|
||||
|
||||
return setApplicationParametersInternal({tlv::ApplicationParameters, std::move(value)});
|
||||
@@ -527,14 +632,14 @@ Interest::isSigned() const noexcept
|
||||
m_name[-1].type() == tlv::ParametersSha256DigestComponent;
|
||||
}
|
||||
|
||||
optional<SignatureInfo>
|
||||
std::optional<SignatureInfo>
|
||||
Interest::getSignatureInfo() const
|
||||
{
|
||||
auto blockIt = findFirstParameter(tlv::InterestSignatureInfo);
|
||||
if (blockIt != m_parameters.end()) {
|
||||
return make_optional<SignatureInfo>(*blockIt, SignatureInfo::Type::Interest);
|
||||
return std::make_optional<SignatureInfo>(*blockIt, SignatureInfo::Type::Interest);
|
||||
}
|
||||
return nullopt;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Interest&
|
||||
@@ -625,8 +730,8 @@ Interest::setSignatureValue(span<const uint8_t> value)
|
||||
Interest&
|
||||
Interest::setSignatureValue(ConstBufferPtr value)
|
||||
{
|
||||
if (value == nullptr) {
|
||||
NDN_THROW(std::invalid_argument("InterestSignatureValue buffer cannot be nullptr"));
|
||||
if (!value) {
|
||||
NDN_THROW(std::invalid_argument("InterestSignatureValue buffer cannot be null"));
|
||||
}
|
||||
|
||||
return setSignatureValueInternal({tlv::InterestSignatureValue, std::move(value)});
|
||||
@@ -758,8 +863,7 @@ operator<<(std::ostream& os, const Interest& interest)
|
||||
auto printOne = [&] (const auto&... args) {
|
||||
os << delim;
|
||||
delim = '&';
|
||||
using expand = int[];
|
||||
(void)expand{(os << args, 0)...}; // use a fold expression when we switch to C++17
|
||||
(os << ... << args);
|
||||
};
|
||||
|
||||
if (interest.getCanBePrefix()) {
|
||||
@@ -782,3 +886,4 @@ operator<<(std::ostream& os, const Interest& interest)
|
||||
}
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
+109
-62
@@ -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).
|
||||
*
|
||||
@@ -40,11 +40,11 @@ class Data;
|
||||
/**
|
||||
* @brief Default value of `InterestLifetime`.
|
||||
*/
|
||||
const time::milliseconds DEFAULT_INTEREST_LIFETIME = 4_s;
|
||||
inline constexpr time::milliseconds DEFAULT_INTEREST_LIFETIME = 4_s;
|
||||
|
||||
/**
|
||||
* @brief Represents an %Interest packet.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/interest.html
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/interest.html
|
||||
*/
|
||||
class Interest : public PacketBase, public std::enable_shared_from_this<Interest>
|
||||
{
|
||||
@@ -55,10 +55,8 @@ public:
|
||||
using tlv::Error::Error;
|
||||
};
|
||||
|
||||
class Nonce final : public std::array<uint8_t, 4>
|
||||
class Nonce final : public std::array<uint8_t, 4>, private boost::equality_comparable<Nonce>
|
||||
{
|
||||
using Base = std::array<uint8_t, 4>;
|
||||
|
||||
public:
|
||||
Nonce() = default;
|
||||
|
||||
@@ -71,26 +69,21 @@ public:
|
||||
|
||||
Nonce(uint8_t n1, uint8_t n2, uint8_t n3, uint8_t n4) noexcept
|
||||
{
|
||||
data()[0] = n1;
|
||||
data()[1] = n2;
|
||||
data()[2] = n3;
|
||||
data()[3] = n4;
|
||||
(*this)[0] = n1;
|
||||
(*this)[1] = n2;
|
||||
(*this)[2] = n3;
|
||||
(*this)[3] = n4;
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
friend bool
|
||||
operator==(const Nonce& lhs, const Nonce& rhs) noexcept
|
||||
{
|
||||
return static_cast<const Base&>(lhs) == static_cast<const Base&>(rhs);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(const Nonce& lhs, const Nonce& rhs) noexcept
|
||||
{
|
||||
return static_cast<const Base&>(lhs) != static_cast<const Base&>(rhs);
|
||||
return std::equal(lhs.begin(), lhs.end(), rhs.begin());
|
||||
}
|
||||
|
||||
friend std::ostream&
|
||||
@@ -153,22 +146,27 @@ public:
|
||||
toUri() const;
|
||||
|
||||
public: // matching
|
||||
/** @brief Check if Interest can be satisfied by @p data.
|
||||
/**
|
||||
* @brief Check if this Interest can be satisfied by @p data.
|
||||
*
|
||||
* This method considers Name, CanBePrefix, and MustBeFresh. However, MustBeFresh processing
|
||||
* is limited to rejecting Data with zero/omitted FreshnessPeriod.
|
||||
* This method considers `Name`, `CanBePrefix`, and `MustBeFresh`. However, `MustBeFresh`
|
||||
* evaluation is limited to rejecting Data with zero/omitted `FreshnessPeriod`.
|
||||
*/
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
matchesData(const Data& data) const;
|
||||
|
||||
/** @brief Check if this Interest matches @p other
|
||||
/**
|
||||
* @brief Check if this Interest matches @p other.
|
||||
*
|
||||
* Two Interests match if both have the same Name, CanBePrefix, and MustBeFresh.
|
||||
* Two Interests match if they have the same `Name`, `CanBePrefix`, and `MustBeFresh`.
|
||||
*/
|
||||
bool
|
||||
[[nodiscard]] bool
|
||||
matchesInterest(const Interest& other) const;
|
||||
|
||||
public: // element access
|
||||
public: // Interest fields
|
||||
/**
|
||||
* @brief Get the %Interest name.
|
||||
*/
|
||||
const Name&
|
||||
getName() const noexcept
|
||||
{
|
||||
@@ -176,8 +174,8 @@ public: // element access
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the %Interest's name.
|
||||
* @throw std::invalid_argument @p name is invalid
|
||||
* @brief Set the %Interest name.
|
||||
* @throw std::invalid_argument @p name is not a valid %Interest name
|
||||
*/
|
||||
Interest&
|
||||
setName(const Name& name);
|
||||
@@ -196,12 +194,7 @@ public: // element access
|
||||
* @param canBePrefix Whether the element should be present.
|
||||
*/
|
||||
Interest&
|
||||
setCanBePrefix(bool canBePrefix)
|
||||
{
|
||||
m_canBePrefix = canBePrefix;
|
||||
m_wire.reset();
|
||||
return *this;
|
||||
}
|
||||
setCanBePrefix(bool canBePrefix);
|
||||
|
||||
/**
|
||||
* @brief Check whether the `MustBeFresh` element is present.
|
||||
@@ -217,19 +210,22 @@ public: // element access
|
||||
* @param mustBeFresh Whether the element should be present.
|
||||
*/
|
||||
Interest&
|
||||
setMustBeFresh(bool mustBeFresh)
|
||||
{
|
||||
m_mustBeFresh = mustBeFresh;
|
||||
m_wire.reset();
|
||||
return *this;
|
||||
}
|
||||
setMustBeFresh(bool mustBeFresh);
|
||||
|
||||
/**
|
||||
* @brief Get the delegations (names) in the `ForwardingHint`.
|
||||
*/
|
||||
span<const Name>
|
||||
getForwardingHint() const noexcept
|
||||
{
|
||||
return m_forwardingHint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the `ForwardingHint` delegations (names).
|
||||
*
|
||||
* To completely remove the `ForwardingHint` element from the Interest, pass an empty vector.
|
||||
*/
|
||||
Interest&
|
||||
setForwardingHint(std::vector<Name> value);
|
||||
|
||||
@@ -253,10 +249,37 @@ public: // element access
|
||||
/**
|
||||
* @brief Set the %Interest's nonce.
|
||||
*
|
||||
* Use `setNonce(nullopt)` to remove any nonce from the Interest.
|
||||
* Use `setNonce(std::nullopt)` to remove any nonce from the Interest.
|
||||
*/
|
||||
Interest&
|
||||
setNonce(optional<Nonce> nonce);
|
||||
setNonce(std::optional<Nonce> nonce);
|
||||
|
||||
std::optional<uint8_t>
|
||||
getServiceClass() const noexcept
|
||||
{
|
||||
return m_serviceClass;
|
||||
}
|
||||
|
||||
const Interest&
|
||||
setServiceClass(std::optional<uint8_t> serviceClass) const;
|
||||
|
||||
std::optional<uint64_t>
|
||||
getDownstreamRate() const noexcept
|
||||
{
|
||||
return m_downstreamRate;
|
||||
}
|
||||
|
||||
const Interest&
|
||||
setDownstreamRate(std::optional<uint64_t> downstreamRate) const;
|
||||
|
||||
std::optional<uint16_t>
|
||||
getDsz() const noexcept
|
||||
{
|
||||
return m_dsz;
|
||||
}
|
||||
|
||||
const Interest&
|
||||
setDsz(std::optional<uint16_t> dsz) const;
|
||||
|
||||
/**
|
||||
* @brief Change nonce value.
|
||||
@@ -286,7 +309,7 @@ public: // element access
|
||||
/**
|
||||
* @brief Get the %Interest's hop limit.
|
||||
*/
|
||||
optional<uint8_t>
|
||||
std::optional<uint8_t>
|
||||
getHopLimit() const noexcept
|
||||
{
|
||||
return m_hopLimit;
|
||||
@@ -295,10 +318,10 @@ public: // element access
|
||||
/**
|
||||
* @brief Set the %Interest's hop limit.
|
||||
*
|
||||
* Use `setHopLimit(nullopt)` to remove any hop limit from the Interest.
|
||||
* Use `setHopLimit(std::nullopt)` to remove any hop limit from the Interest.
|
||||
*/
|
||||
Interest&
|
||||
setHopLimit(optional<uint8_t> hopLimit);
|
||||
setHopLimit(std::optional<uint8_t> hopLimit);
|
||||
|
||||
/**
|
||||
* @brief Return whether this Interest has any `ApplicationParameters` element.
|
||||
@@ -353,9 +376,21 @@ public: // element access
|
||||
Interest&
|
||||
setApplicationParameters(span<const uint8_t> value);
|
||||
|
||||
/**
|
||||
* @brief Set `ApplicationParameters` by copying from a string.
|
||||
* @param value string from which the TLV-VALUE of the parameters will be copied
|
||||
* @return A reference to this Interest.
|
||||
*
|
||||
* This function will also recompute the value of the ParametersSha256DigestComponent in the
|
||||
* Interest's name. If the name does not contain a ParametersSha256DigestComponent, one will
|
||||
* be appended to it.
|
||||
*/
|
||||
Interest&
|
||||
setApplicationParameters(std::string_view value);
|
||||
|
||||
/**
|
||||
* @brief Set `ApplicationParameters` from a shared buffer.
|
||||
* @param value buffer containing the TLV-VALUE of the parameters; must not be nullptr
|
||||
* @param value buffer containing the TLV-VALUE of the parameters; must not be null
|
||||
* @return A reference to this Interest.
|
||||
*
|
||||
* This function will also recompute the value of the ParametersSha256DigestComponent in the
|
||||
@@ -365,6 +400,9 @@ public: // element access
|
||||
Interest&
|
||||
setApplicationParameters(ConstBufferPtr value);
|
||||
|
||||
Interest&
|
||||
setApplicationParameters(std::nullptr_t) = delete;
|
||||
|
||||
/**
|
||||
* @brief Remove the `ApplicationParameters` element from this Interest.
|
||||
* @return A reference to this Interest.
|
||||
@@ -386,9 +424,8 @@ public: // element access
|
||||
|
||||
/**
|
||||
* @brief Get the `InterestSignatureInfo` element.
|
||||
* @retval nullopt The element is not present.
|
||||
*/
|
||||
optional<SignatureInfo>
|
||||
std::optional<SignatureInfo>
|
||||
getSignatureInfo() const;
|
||||
|
||||
/**
|
||||
@@ -418,7 +455,7 @@ public: // element access
|
||||
|
||||
/**
|
||||
* @brief Set `InterestSignatureValue` from a shared buffer.
|
||||
* @param value buffer containing the TLV-VALUE of the InterestSignatureValue; must not be nullptr
|
||||
* @param value buffer containing the TLV-VALUE of the InterestSignatureValue; must not be null
|
||||
* @return A reference to this Interest.
|
||||
* @throw Error InterestSignatureInfo is unset
|
||||
*
|
||||
@@ -427,11 +464,15 @@ public: // element access
|
||||
Interest&
|
||||
setSignatureValue(ConstBufferPtr value);
|
||||
|
||||
/** @brief Extract ranges of Interest covered by the signature in Packet Specification v0.3
|
||||
* @throw Error Interest cannot be encoded or is missing ranges necessary for signing
|
||||
* @warning The returned pointers will be invalidated if wireDecode() or wireEncode() are called.
|
||||
Interest&
|
||||
setSignatureValue(std::nullptr_t) = delete;
|
||||
|
||||
/**
|
||||
* @brief Extract ranges of Interest covered by the signature.
|
||||
* @throw Error Interest 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;
|
||||
|
||||
public: // ParametersSha256DigestComponent support
|
||||
@@ -447,12 +488,13 @@ public: // ParametersSha256DigestComponent support
|
||||
s_autoCheckParametersDigest = b;
|
||||
}
|
||||
|
||||
/** @brief Check if the ParametersSha256DigestComponent in the name is valid.
|
||||
/**
|
||||
* @brief Check if the ParametersSha256DigestComponent in the name is valid.
|
||||
*
|
||||
* Returns true if there is a single ParametersSha256DigestComponent in the name and the digest
|
||||
* value is correct, or if there is no ParametersSha256DigestComponent in the name and the
|
||||
* Interest does not contain any parameters.
|
||||
* Returns false otherwise.
|
||||
* Returns true if there is a single ParametersSha256DigestComponent in the name and the digest
|
||||
* value is correct, or if there is no ParametersSha256DigestComponent in the name and the
|
||||
* Interest does not contain any parameters.
|
||||
* Returns false otherwise.
|
||||
*/
|
||||
bool
|
||||
isParametersDigestValid() const;
|
||||
@@ -464,7 +506,7 @@ private:
|
||||
Interest&
|
||||
setSignatureValueInternal(Block sigValue);
|
||||
|
||||
NDN_CXX_NODISCARD shared_ptr<Buffer>
|
||||
[[nodiscard]] shared_ptr<Buffer>
|
||||
computeParametersDigest() const;
|
||||
|
||||
/** @brief Append a ParametersSha256DigestComponent to the Interest's name
|
||||
@@ -490,13 +532,15 @@ private:
|
||||
findFirstParameter(uint32_t type) const;
|
||||
|
||||
private:
|
||||
static bool s_autoCheckParametersDigest;
|
||||
|
||||
Name m_name;
|
||||
std::vector<Name> m_forwardingHint;
|
||||
mutable optional<Nonce> m_nonce;
|
||||
mutable std::optional<Nonce> m_nonce;
|
||||
// Add for QSCCP
|
||||
mutable std::optional<uint8_t> m_serviceClass;
|
||||
mutable std::optional<uint64_t> m_downstreamRate;
|
||||
mutable std::optional<uint16_t> m_dsz;
|
||||
time::milliseconds m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
|
||||
optional<uint8_t> m_hopLimit;
|
||||
std::optional<uint8_t> m_hopLimit;
|
||||
bool m_canBePrefix = false;
|
||||
bool m_mustBeFresh = false;
|
||||
|
||||
@@ -509,6 +553,8 @@ private:
|
||||
std::vector<Block> m_parameters;
|
||||
|
||||
mutable Block m_wire;
|
||||
|
||||
static inline bool s_autoCheckParametersDigest = true;
|
||||
};
|
||||
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Interest);
|
||||
@@ -519,3 +565,4 @@ operator<<(std::ostream& os, const Interest& interest);
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_CXX_INTEREST_HPP
|
||||
|
||||
+18
-26
@@ -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,14 +27,7 @@
|
||||
|
||||
namespace ndn {
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<KeyLocator>));
|
||||
BOOST_CONCEPT_ASSERT((WireEncodable<KeyLocator>));
|
||||
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<KeyLocator>));
|
||||
BOOST_CONCEPT_ASSERT((WireDecodable<KeyLocator>));
|
||||
static_assert(std::is_base_of<tlv::Error, KeyLocator::Error>::value,
|
||||
"KeyLocator::Error must inherit from tlv::Error");
|
||||
|
||||
const size_t MAX_KEY_DIGEST_OCTETS_TO_SHOW = 8;
|
||||
constexpr size_t MAX_KEY_DIGEST_OCTETS_TO_SHOW = 8;
|
||||
|
||||
KeyLocator::KeyLocator() = default;
|
||||
|
||||
@@ -57,12 +50,12 @@ KeyLocator::wireEncode(EncodingImpl<TAG>& encoder) const
|
||||
|
||||
size_t totalLength = 0;
|
||||
|
||||
auto visitor = boost::hana::overload(
|
||||
[] (monostate) {}, // nothing to encode, TLV-VALUE is empty
|
||||
std::visit(boost::hana::overload(
|
||||
[] (std::monostate) {}, // nothing to encode, TLV-VALUE is empty
|
||||
[&] (const Name& name) { totalLength += name.wireEncode(encoder); },
|
||||
[&] (const Block& digest) { totalLength += prependBlock(encoder, digest); },
|
||||
[] (uint32_t type) { NDN_THROW(Error("Unsupported KeyLocator type " + to_string(type))); });
|
||||
visit(visitor, m_locator);
|
||||
[] (uint32_t type) { NDN_THROW(Error("Unsupported KeyLocator type " + to_string(type))); }),
|
||||
m_locator);
|
||||
|
||||
totalLength += encoder.prependVarNumber(totalLength);
|
||||
totalLength += encoder.prependVarNumber(tlv::KeyLocator);
|
||||
@@ -126,7 +119,7 @@ KeyLocator::getType() const
|
||||
case 2:
|
||||
return tlv::KeyDigest;
|
||||
case 3:
|
||||
return get<uint32_t>(m_locator);
|
||||
return std::get<uint32_t>(m_locator);
|
||||
default:
|
||||
NDN_CXX_UNREACHABLE;
|
||||
}
|
||||
@@ -135,7 +128,7 @@ KeyLocator::getType() const
|
||||
KeyLocator&
|
||||
KeyLocator::clear()
|
||||
{
|
||||
m_locator = monostate{};
|
||||
m_locator = std::monostate{};
|
||||
m_wire.reset();
|
||||
return *this;
|
||||
}
|
||||
@@ -144,9 +137,9 @@ const Name&
|
||||
KeyLocator::getName() const
|
||||
{
|
||||
try {
|
||||
return get<Name>(m_locator);
|
||||
return std::get<Name>(m_locator);
|
||||
}
|
||||
catch (const bad_variant_access&) {
|
||||
catch (const std::bad_variant_access&) {
|
||||
NDN_THROW(Error("KeyLocator does not contain a Name"));
|
||||
}
|
||||
}
|
||||
@@ -163,9 +156,9 @@ const Block&
|
||||
KeyLocator::getKeyDigest() const
|
||||
{
|
||||
try {
|
||||
return get<Block>(m_locator);
|
||||
return std::get<Block>(m_locator);
|
||||
}
|
||||
catch (const bad_variant_access&) {
|
||||
catch (const std::bad_variant_access&) {
|
||||
NDN_THROW(Error("KeyLocator does not contain a KeyDigest"));
|
||||
}
|
||||
}
|
||||
@@ -190,11 +183,11 @@ KeyLocator::setKeyDigest(const ConstBufferPtr& keyDigest)
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const KeyLocator& keyLocator)
|
||||
void
|
||||
KeyLocator::print(std::ostream& os) const
|
||||
{
|
||||
auto visitor = boost::hana::overload(
|
||||
[&] (monostate) {
|
||||
std::visit(boost::hana::overload(
|
||||
[&] (std::monostate) {
|
||||
os << "None";
|
||||
},
|
||||
[&] (const Name& name) {
|
||||
@@ -209,9 +202,8 @@ operator<<(std::ostream& os, const KeyLocator& keyLocator)
|
||||
},
|
||||
[&] (uint32_t type) {
|
||||
os << "Unknown(" << type << ")";
|
||||
});
|
||||
visit(visitor, keyLocator.m_locator);
|
||||
return os;
|
||||
}),
|
||||
m_locator);
|
||||
}
|
||||
|
||||
} // namespace ndn
|
||||
+16
-14
@@ -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,11 +23,12 @@
|
||||
#define NDN_CXX_KEY_LOCATOR_HPP
|
||||
|
||||
#include "ndn-cxx/name.hpp"
|
||||
#include "ndn-cxx/util/variant.hpp"
|
||||
|
||||
#include <variant>
|
||||
|
||||
namespace ndn {
|
||||
|
||||
class KeyLocator
|
||||
class KeyLocator : private boost::equality_comparable<KeyLocator>
|
||||
{
|
||||
public:
|
||||
class Error : public tlv::Error
|
||||
@@ -71,10 +72,10 @@ public: // encode and decode
|
||||
wireDecode(const Block& wire);
|
||||
|
||||
public: // attributes
|
||||
NDN_CXX_NODISCARD bool
|
||||
[[nodiscard]] bool
|
||||
empty() const
|
||||
{
|
||||
return holds_alternative<monostate>(m_locator);
|
||||
return std::holds_alternative<std::monostate>(m_locator);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -123,9 +124,14 @@ public: // attributes
|
||||
KeyLocator&
|
||||
setKeyDigest(const ConstBufferPtr& keyDigest);
|
||||
|
||||
private:
|
||||
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.
|
||||
|
||||
friend bool
|
||||
operator==(const KeyLocator& lhs, const KeyLocator& rhs)
|
||||
@@ -133,10 +139,11 @@ private: // non-member operators
|
||||
return lhs.m_locator == rhs.m_locator;
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator!=(const KeyLocator& lhs, const KeyLocator& rhs)
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, const KeyLocator& kl)
|
||||
{
|
||||
return lhs.m_locator != rhs.m_locator;
|
||||
kl.print(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -144,18 +151,13 @@ private:
|
||||
// - Name is used when the nested TLV contains a name
|
||||
// - Block is used when the nested TLV is a KeyDigest
|
||||
// - in all other (unsupported) cases the nested TLV type is stored as uint32_t
|
||||
variant<monostate, Name, Block, uint32_t> m_locator;
|
||||
std::variant<std::monostate, Name, Block, uint32_t> m_locator;
|
||||
|
||||
mutable Block m_wire;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream&, const KeyLocator&);
|
||||
};
|
||||
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(KeyLocator);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const KeyLocator& keyLocator);
|
||||
|
||||
} // namespace ndn
|
||||
|
||||
#endif // NDN_CXX_KEY_LOCATOR_HPP
|
||||
+4
-15
@@ -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).
|
||||
*
|
||||
@@ -21,14 +21,9 @@
|
||||
|
||||
#include "ndn-cxx/link.hpp"
|
||||
|
||||
namespace ndn {
|
||||
#include <algorithm>
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Link>));
|
||||
BOOST_CONCEPT_ASSERT((WireEncodable<Link>));
|
||||
BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Link>));
|
||||
BOOST_CONCEPT_ASSERT((WireDecodable<Link>));
|
||||
static_assert(std::is_base_of<Data::Error, Link::Error>::value,
|
||||
"Link::Error should inherit from Data::Error");
|
||||
namespace ndn {
|
||||
|
||||
Link::Link() = default;
|
||||
|
||||
@@ -48,13 +43,7 @@ void
|
||||
Link::encodeContent()
|
||||
{
|
||||
setContentType(tlv::ContentType_Link);
|
||||
|
||||
if (m_delegations.empty()) {
|
||||
setContent(span<uint8_t>{});
|
||||
}
|
||||
else {
|
||||
setContent(makeNestedBlock(tlv::Content, m_delegations.begin(), m_delegations.end()));
|
||||
}
|
||||
setContent(makeNestedBlock(tlv::Content, m_delegations.begin(), m_delegations.end()));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+4
-2
@@ -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,11 +24,13 @@
|
||||
|
||||
#include "ndn-cxx/data.hpp"
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
namespace ndn {
|
||||
|
||||
/**
|
||||
* @brief Represents a `%LinkObject` TLV element.
|
||||
* @sa https://named-data.net/doc/NDN-packet-spec/0.3/link.html
|
||||
* @sa https://docs.named-data.net/NDN-packet-spec/0.3/link.html
|
||||
*/
|
||||
class Link : public Data
|
||||
{
|
||||
|
||||
@@ -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/lp/cache-policy.hpp"
|
||||
#include "ndn-cxx/encoding/block-helpers.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace lp {
|
||||
namespace ndn::lp {
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, CachePolicyType policy)
|
||||
@@ -132,5 +131,4 @@ CachePolicy::setPolicy(CachePolicyType policy)
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
@@ -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,8 +27,7 @@
|
||||
#include "ndn-cxx/encoding/encoding-buffer.hpp"
|
||||
#include "ndn-cxx/lp/tlv.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace lp {
|
||||
namespace ndn::lp {
|
||||
|
||||
/**
|
||||
* \brief Indicates the cache policy applied to a Data packet.
|
||||
@@ -101,7 +100,6 @@ private:
|
||||
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(CachePolicy);
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
|
||||
#endif // NDN_CXX_LP_CACHE_POLICY_HPP
|
||||
@@ -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 @@
|
||||
#ifndef NDN_CXX_LP_TLV_EMPTY_VALUE_HPP
|
||||
#define NDN_CXX_LP_TLV_EMPTY_VALUE_HPP
|
||||
|
||||
namespace ndn {
|
||||
namespace lp {
|
||||
namespace ndn::lp {
|
||||
|
||||
/**
|
||||
* \brief Represents a zero-length TLV-VALUE.
|
||||
@@ -34,7 +33,6 @@ struct EmptyValue
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
|
||||
#endif // NDN_CXX_LP_TLV_EMPTY_VALUE_HPP
|
||||
+11
-15
@@ -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).
|
||||
*
|
||||
@@ -22,20 +22,17 @@
|
||||
#ifndef NDN_CXX_LP_FIELD_DECL_HPP
|
||||
#define NDN_CXX_LP_FIELD_DECL_HPP
|
||||
|
||||
#include "ndn-cxx/lp/empty-value.hpp"
|
||||
#include "ndn-cxx/lp/field.hpp"
|
||||
#include "ndn-cxx/lp/sequence.hpp"
|
||||
#include "ndn-cxx/lp/tlv.hpp"
|
||||
#include "ndn-cxx/encoding/block-helpers.hpp"
|
||||
#include "ndn-cxx/lp/empty-value.hpp"
|
||||
#include "ndn-cxx/util/concepts.hpp"
|
||||
|
||||
#include <boost/concept/requires.hpp>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
|
||||
namespace ndn {
|
||||
namespace lp {
|
||||
namespace ndn::lp {
|
||||
|
||||
/** \brief Indicate a uint64_t field shall be decoded and encoded as a non-negative integer.
|
||||
/**
|
||||
* \brief Indicates that a `uint64_t` field shall be decoded and encoded as a non-negative integer.
|
||||
*/
|
||||
struct NonNegativeIntegerTag;
|
||||
|
||||
@@ -171,15 +168,15 @@ struct EncodeHelper<TAG, TlvType, std::pair<Buffer::const_iterator, Buffer::cons
|
||||
* \tparam DECODER_TAG selects a specialization of DecodeHelper.
|
||||
* \tparam ENCODER_TAG selects a specialization of EncodeHelper.
|
||||
*/
|
||||
template<typename LOCATION, typename VALUE, uint64_t TYPE, bool REPEATABLE = false,
|
||||
template<typename LOCATION, typename VALUE, uint32_t TYPE, bool REPEATABLE = false,
|
||||
typename DECODER_TAG = VALUE, typename ENCODER_TAG = VALUE>
|
||||
class FieldDecl
|
||||
{
|
||||
public:
|
||||
typedef LOCATION FieldLocation;
|
||||
typedef VALUE ValueType;
|
||||
typedef std::integral_constant<uint64_t, TYPE> TlvType;
|
||||
typedef std::integral_constant<bool, REPEATABLE> IsRepeatable;
|
||||
using FieldLocation = LOCATION;
|
||||
using ValueType = VALUE;
|
||||
using TlvType = std::integral_constant<uint32_t, TYPE>;
|
||||
using IsRepeatable = std::bool_constant<REPEATABLE>;
|
||||
|
||||
/** \brief Decode a field.
|
||||
* \param wire an element with top-level TLV-TYPE \c TlvType::value.
|
||||
@@ -208,7 +205,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
|
||||
#endif // NDN_CXX_LP_FIELD_DECL_HPP
|
||||
+14
-24
@@ -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).
|
||||
*
|
||||
@@ -22,49 +22,40 @@
|
||||
#ifndef NDN_CXX_LP_FIELD_HPP
|
||||
#define NDN_CXX_LP_FIELD_HPP
|
||||
|
||||
#include "ndn-cxx/detail/common.hpp"
|
||||
#include "ndn-cxx/encoding/encoding-buffer.hpp"
|
||||
#include "ndn-cxx/util/concepts.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace lp {
|
||||
#include <boost/concept/usage.hpp>
|
||||
|
||||
namespace ndn::lp {
|
||||
|
||||
/**
|
||||
* \brief Indicates where a field may occur.
|
||||
*/
|
||||
namespace field_location_tags {
|
||||
|
||||
class Base
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A header field.
|
||||
*/
|
||||
class Header : public Base
|
||||
{
|
||||
};
|
||||
struct Header {};
|
||||
|
||||
/**
|
||||
* \brief The Fragment field.
|
||||
*/
|
||||
class Fragment : public Base
|
||||
{
|
||||
};
|
||||
struct Fragment {};
|
||||
|
||||
} // namespace field_location_tags
|
||||
|
||||
/**
|
||||
* \brief Concept check for fields.
|
||||
* \brief Concept check for NDNLPv2 fields.
|
||||
*/
|
||||
template<class X>
|
||||
template<typename X>
|
||||
struct Field
|
||||
{
|
||||
static_assert(std::is_base_of<field_location_tags::Base, typename X::FieldLocation>::value, "");
|
||||
static_assert(std::is_same<typename X::TlvType::value_type, uint64_t>::value, "");
|
||||
static_assert(std::is_same<typename X::IsRepeatable::value_type, bool>::value, "");
|
||||
static_assert(std::is_default_constructible<typename X::ValueType>::value, "");
|
||||
static_assert(std::is_copy_constructible<typename X::ValueType>::value, "");
|
||||
static_assert(std::is_same_v<typename X::TlvType::value_type, uint32_t>);
|
||||
static_assert(std::is_same_v<typename X::IsRepeatable::value_type, bool>);
|
||||
static_assert(std::is_default_constructible_v<typename X::ValueType>);
|
||||
static_assert(std::is_copy_constructible_v<typename X::ValueType>);
|
||||
|
||||
BOOST_CONCEPT_USAGE(Field)
|
||||
{
|
||||
Block wire;
|
||||
@@ -75,7 +66,6 @@ struct Field
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
|
||||
#endif // NDN_CXX_LP_FIELD_HPP
|
||||
+71
-44
@@ -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).
|
||||
*
|
||||
@@ -22,21 +22,33 @@
|
||||
#ifndef NDN_CXX_LP_FIELDS_HPP
|
||||
#define NDN_CXX_LP_FIELDS_HPP
|
||||
|
||||
#include "ndn-cxx/lp/field-decl.hpp"
|
||||
|
||||
#include "ndn-cxx/lp/cache-policy.hpp"
|
||||
#include "ndn-cxx/lp/empty-value.hpp"
|
||||
#include "ndn-cxx/lp/field.hpp"
|
||||
#include "ndn-cxx/lp/field-decl.hpp"
|
||||
#include "ndn-cxx/lp/nack-header.hpp"
|
||||
#include "ndn-cxx/lp/prefix-announcement-header.hpp"
|
||||
#include "ndn-cxx/lp/sequence.hpp"
|
||||
#include "ndn-cxx/lp/tlv.hpp"
|
||||
|
||||
#include <boost/mpl/set.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/set.hpp>
|
||||
|
||||
namespace ndn {
|
||||
namespace lp {
|
||||
namespace ndn::lp {
|
||||
|
||||
/**
|
||||
* \brief Declare the Fragment field.
|
||||
*
|
||||
* The fragment (i.e., payload) is the range of bytes between two provided iterators.
|
||||
* During encoding, these bytes are copied from the Buffer into the LpPacket.
|
||||
*/
|
||||
typedef FieldDecl<field_location_tags::Fragment,
|
||||
std::pair<Buffer::const_iterator, Buffer::const_iterator>,
|
||||
tlv::Fragment> FragmentField;
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
Sequence,
|
||||
tlv::Sequence> SequenceField;
|
||||
BOOST_CONCEPT_ASSERT((Field<SequenceField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t,
|
||||
@@ -44,7 +56,6 @@ typedef FieldDecl<field_location_tags::Header,
|
||||
false,
|
||||
NonNegativeIntegerTag,
|
||||
NonNegativeIntegerTag> FragIndexField;
|
||||
BOOST_CONCEPT_ASSERT((Field<FragIndexField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t,
|
||||
@@ -52,30 +63,14 @@ typedef FieldDecl<field_location_tags::Header,
|
||||
false,
|
||||
NonNegativeIntegerTag,
|
||||
NonNegativeIntegerTag> FragCountField;
|
||||
BOOST_CONCEPT_ASSERT((Field<FragCountField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
std::pair<Buffer::const_iterator, Buffer::const_iterator>,
|
||||
tlv::PitToken> PitTokenField;
|
||||
BOOST_CONCEPT_ASSERT((Field<PitTokenField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
NackHeader,
|
||||
tlv::Nack> NackField;
|
||||
BOOST_CONCEPT_ASSERT((Field<NackField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t,
|
||||
tlv::NextHopFaceId,
|
||||
false,
|
||||
NonNegativeIntegerTag,
|
||||
NonNegativeIntegerTag> NextHopFaceIdField;
|
||||
BOOST_CONCEPT_ASSERT((Field<NextHopFaceIdField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
CachePolicy,
|
||||
tlv::CachePolicy> CachePolicyField;
|
||||
BOOST_CONCEPT_ASSERT((Field<CachePolicyField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t,
|
||||
@@ -83,7 +78,17 @@ typedef FieldDecl<field_location_tags::Header,
|
||||
false,
|
||||
NonNegativeIntegerTag,
|
||||
NonNegativeIntegerTag> IncomingFaceIdField;
|
||||
BOOST_CONCEPT_ASSERT((Field<IncomingFaceIdField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t,
|
||||
tlv::NextHopFaceId,
|
||||
false,
|
||||
NonNegativeIntegerTag,
|
||||
NonNegativeIntegerTag> NextHopFaceIdField;
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
CachePolicy,
|
||||
tlv::CachePolicy> CachePolicyField;
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t,
|
||||
@@ -91,42 +96,59 @@ typedef FieldDecl<field_location_tags::Header,
|
||||
false,
|
||||
NonNegativeIntegerTag,
|
||||
NonNegativeIntegerTag> CongestionMarkField;
|
||||
BOOST_CONCEPT_ASSERT((Field<CongestionMarkField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
Sequence,
|
||||
tlv::Ack,
|
||||
true> AckField;
|
||||
BOOST_CONCEPT_ASSERT((Field<AckField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
Sequence,
|
||||
tlv::TxSequence> TxSequenceField;
|
||||
BOOST_CONCEPT_ASSERT((Field<TxSequenceField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
EmptyValue,
|
||||
tlv::NonDiscovery> NonDiscoveryField;
|
||||
BOOST_CONCEPT_ASSERT((Field<NonDiscoveryField>));
|
||||
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
PrefixAnnouncementHeader,
|
||||
tlv::PrefixAnnouncement> PrefixAnnouncementField;
|
||||
BOOST_CONCEPT_ASSERT((Field<PrefixAnnouncementField>));
|
||||
|
||||
/** \brief Declare the Fragment field.
|
||||
*
|
||||
* The fragment (i.e. payload) is the bytes between two provided iterators. During encoding,
|
||||
* these bytes are copied from the Buffer into the LpPacket.
|
||||
/**
|
||||
* DSZ Field
|
||||
* Data Size field
|
||||
*/
|
||||
typedef FieldDecl<field_location_tags::Fragment,
|
||||
std::pair<Buffer::const_iterator, Buffer::const_iterator>,
|
||||
tlv::Fragment> FragmentField;
|
||||
BOOST_CONCEPT_ASSERT((Field<FragmentField>));
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t, tlv::DSZ> DSZField;
|
||||
|
||||
/** \brief Set of all field declarations.
|
||||
/**
|
||||
* Tos Field
|
||||
*/
|
||||
typedef boost::mpl::set<
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t, tlv::Tos> TosField;
|
||||
|
||||
/**
|
||||
* Fair rate field
|
||||
*/
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t, tlv::TargetRate> TargetRateField;
|
||||
|
||||
///**
|
||||
// * Queue occupy rate
|
||||
// */
|
||||
//typedef FieldDecl<field_location_tags::Header,
|
||||
// uint64_t, tlv::QueueOccupyRate> QueueOccupyRateField;
|
||||
//BOOST_CONCEPT_ASSERT((Field<QueueOccupyRateField>));
|
||||
/**
|
||||
* Available rate field
|
||||
*/
|
||||
typedef FieldDecl<field_location_tags::Header,
|
||||
uint64_t, tlv::DownstreamRate> DownstreamRateField;
|
||||
|
||||
/**
|
||||
* \brief Set of all field declarations.
|
||||
*/
|
||||
using FieldSet = boost::mp11::mp_list<
|
||||
FragmentField,
|
||||
SequenceField,
|
||||
FragIndexField,
|
||||
@@ -140,10 +162,15 @@ typedef boost::mpl::set<
|
||||
AckField,
|
||||
TxSequenceField,
|
||||
NonDiscoveryField,
|
||||
PrefixAnnouncementField
|
||||
> FieldSet;
|
||||
PrefixAnnouncementField,
|
||||
DSZField,
|
||||
TosField,
|
||||
TargetRateField,
|
||||
// QueueOccupyRateField,
|
||||
DownstreamRateField
|
||||
>;
|
||||
static_assert(boost::mp11::mp_is_set<FieldSet>());
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
|
||||
#endif // NDN_CXX_LP_FIELDS_HPP
|
||||
@@ -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 "ndn-cxx/lp/nack-header.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace lp {
|
||||
namespace ndn::lp {
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, NackReason reason)
|
||||
@@ -138,5 +137,4 @@ NackHeader::setReason(NackReason reason)
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
@@ -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).
|
||||
*
|
||||
@@ -28,8 +28,7 @@
|
||||
#include "ndn-cxx/encoding/encoding-buffer.hpp"
|
||||
#include "ndn-cxx/lp/tlv.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace lp {
|
||||
namespace ndn::lp {
|
||||
|
||||
/**
|
||||
* \brief Indicates the reason type of a %Network %Nack.
|
||||
@@ -95,7 +94,6 @@ private:
|
||||
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(NackHeader);
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
|
||||
#endif // NDN_CXX_LP_NACK_HEADER_HPP
|
||||
+3
-5
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2019 Regents of the University of California.
|
||||
* Copyright (c) 2013-2023 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -23,8 +23,7 @@
|
||||
|
||||
#include "ndn-cxx/lp/nack.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace lp {
|
||||
namespace ndn::lp {
|
||||
|
||||
Nack::Nack() = default;
|
||||
|
||||
@@ -38,5 +37,4 @@ Nack::Nack(Interest&& interest)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
+3
-5
@@ -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).
|
||||
*
|
||||
@@ -28,8 +28,7 @@
|
||||
#include "ndn-cxx/detail/packet-base.hpp"
|
||||
#include "ndn-cxx/lp/nack-header.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace lp {
|
||||
namespace ndn::lp {
|
||||
|
||||
/**
|
||||
* \brief Represents a %Network %Nack.
|
||||
@@ -105,7 +104,6 @@ private:
|
||||
NackHeader m_header;
|
||||
};
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
|
||||
#endif // NDN_CXX_LP_NACK_HPP
|
||||
+27
-58
@@ -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).
|
||||
*
|
||||
@@ -22,73 +22,48 @@
|
||||
#include "ndn-cxx/lp/packet.hpp"
|
||||
#include "ndn-cxx/lp/fields.hpp"
|
||||
|
||||
#include <boost/bind/bind.hpp>
|
||||
#include <boost/mpl/for_each.hpp>
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
|
||||
namespace ndn {
|
||||
namespace lp {
|
||||
namespace ndn::lp {
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename TAG>
|
||||
int
|
||||
getLocationSortOrder() noexcept;
|
||||
|
||||
template<>
|
||||
constexpr int
|
||||
getLocationSortOrder<field_location_tags::Header>() noexcept
|
||||
template<typename Tag>
|
||||
constexpr int8_t
|
||||
getLocationSortOrder() noexcept
|
||||
{
|
||||
return 1;
|
||||
if constexpr (std::is_same_v<Tag, field_location_tags::Header>)
|
||||
return 1;
|
||||
if constexpr (std::is_same_v<Tag, field_location_tags::Fragment>)
|
||||
return 2;
|
||||
}
|
||||
|
||||
template<>
|
||||
constexpr int
|
||||
getLocationSortOrder<field_location_tags::Fragment>() noexcept
|
||||
struct FieldInfo
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
class FieldInfo
|
||||
{
|
||||
public:
|
||||
constexpr
|
||||
FieldInfo() noexcept = default;
|
||||
|
||||
explicit
|
||||
FieldInfo(uint64_t tlv) noexcept;
|
||||
FieldInfo(uint32_t type) noexcept;
|
||||
|
||||
public:
|
||||
uint64_t tlvType = 0; ///< TLV-TYPE of the field; 0 if field does not exist
|
||||
uint32_t tlvType = 0; ///< TLV-TYPE of the field; 0 if field does not exist
|
||||
bool isRecognized = false; ///< is this field known
|
||||
bool canIgnore = false; ///< can this unknown field be ignored
|
||||
bool isRepeatable = false; ///< is the field repeatable
|
||||
int locationSortOrder = getLocationSortOrder<field_location_tags::Header>(); ///< sort order of field_location_tag
|
||||
int8_t locationSortOrder = getLocationSortOrder<field_location_tags::Header>(); ///< sort order of field_location_tag
|
||||
};
|
||||
|
||||
class ExtractFieldInfo
|
||||
FieldInfo::FieldInfo(uint32_t type) noexcept
|
||||
: tlvType(type)
|
||||
{
|
||||
public:
|
||||
using result_type = void;
|
||||
|
||||
template<typename T>
|
||||
constexpr void
|
||||
operator()(FieldInfo* info, const T&) const noexcept
|
||||
{
|
||||
if (T::TlvType::value != info->tlvType) {
|
||||
return;
|
||||
boost::mp11::mp_for_each<FieldSet>([this] (auto fieldDecl) {
|
||||
if (tlvType == decltype(fieldDecl)::TlvType::value) {
|
||||
isRecognized = true;
|
||||
isRepeatable = decltype(fieldDecl)::IsRepeatable::value;
|
||||
locationSortOrder = getLocationSortOrder<typename decltype(fieldDecl)::FieldLocation>();
|
||||
}
|
||||
info->isRecognized = true;
|
||||
info->canIgnore = false;
|
||||
info->isRepeatable = T::IsRepeatable::value;
|
||||
info->locationSortOrder = getLocationSortOrder<typename T::FieldLocation>();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
FieldInfo::FieldInfo(uint64_t tlv) noexcept
|
||||
: tlvType(tlv)
|
||||
{
|
||||
boost::mpl::for_each<FieldSet>(boost::bind(ExtractFieldInfo(), this, _1));
|
||||
if (!isRecognized) {
|
||||
canIgnore = tlv::HEADER3_MIN <= tlvType &&
|
||||
tlvType <= tlv::HEADER3_MAX &&
|
||||
@@ -105,10 +80,7 @@ compareFieldSortOrder(const FieldInfo& first, const FieldInfo& second) noexcept
|
||||
|
||||
} // namespace
|
||||
|
||||
Packet::Packet()
|
||||
: m_wire(Block(tlv::LpPacket))
|
||||
{
|
||||
}
|
||||
Packet::Packet() = default;
|
||||
|
||||
Packet::Packet(const Block& wire)
|
||||
{
|
||||
@@ -119,7 +91,7 @@ Block
|
||||
Packet::wireEncode() const
|
||||
{
|
||||
// If no header or trailer, return bare network packet
|
||||
Block::element_container elements = m_wire.elements();
|
||||
auto elements = m_wire.elements();
|
||||
if (elements.size() == 1 && elements.front().type() == FragmentField::TlvType::value) {
|
||||
elements.front().parse();
|
||||
return elements.front().elements().front();
|
||||
@@ -171,12 +143,9 @@ Packet::wireDecode(const Block& wire)
|
||||
}
|
||||
|
||||
bool
|
||||
Packet::comparePos(uint64_t first, const Block& second) noexcept
|
||||
Packet::comparePos(uint32_t first, const Block& second) noexcept
|
||||
{
|
||||
FieldInfo firstInfo(first);
|
||||
FieldInfo secondInfo(second.type());
|
||||
return compareFieldSortOrder(firstInfo, secondInfo);
|
||||
return compareFieldSortOrder(FieldInfo(first), FieldInfo(second.type()));
|
||||
}
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
+12
-12
@@ -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).
|
||||
*
|
||||
@@ -22,13 +22,14 @@
|
||||
#ifndef NDN_CXX_LP_PACKET_HPP
|
||||
#define NDN_CXX_LP_PACKET_HPP
|
||||
|
||||
#include "ndn-cxx/lp/fields.hpp"
|
||||
#include "ndn-cxx/encoding/block.hpp"
|
||||
#include "ndn-cxx/encoding/encoding-buffer.hpp"
|
||||
#include "ndn-cxx/lp/tlv.hpp"
|
||||
|
||||
namespace ndn {
|
||||
/**
|
||||
* @brief Contains classes and functions related to NDNLPv2.
|
||||
*/
|
||||
namespace lp {
|
||||
namespace ndn::lp {
|
||||
|
||||
class Packet
|
||||
{
|
||||
@@ -61,7 +62,7 @@ public:
|
||||
* \retval true packet has no field
|
||||
* \retval false packet has one or more fields
|
||||
*/
|
||||
NDN_CXX_NODISCARD bool
|
||||
[[nodiscard]] bool
|
||||
empty() const
|
||||
{
|
||||
return m_wire.elements_size() == 0;
|
||||
@@ -73,7 +74,7 @@ public: // field access
|
||||
* \details This is equivalent to count() > 0
|
||||
*/
|
||||
template<typename FIELD>
|
||||
NDN_CXX_NODISCARD bool
|
||||
[[nodiscard]] bool
|
||||
has() const
|
||||
{
|
||||
return count<FIELD>() > 0;
|
||||
@@ -83,7 +84,7 @@ public: // field access
|
||||
* \brief Returns the number of occurrences of \c FIELD.
|
||||
*/
|
||||
template<typename FIELD>
|
||||
NDN_CXX_NODISCARD size_t
|
||||
[[nodiscard]] size_t
|
||||
count() const
|
||||
{
|
||||
return std::count_if(m_wire.elements_begin(), m_wire.elements_end(),
|
||||
@@ -115,7 +116,7 @@ public: // field access
|
||||
* \brief Returns the values of all occurrences of \c FIELD.
|
||||
*/
|
||||
template<typename FIELD>
|
||||
NDN_CXX_NODISCARD std::vector<typename FIELD::ValueType>
|
||||
[[nodiscard]] std::vector<typename FIELD::ValueType>
|
||||
list() const
|
||||
{
|
||||
std::vector<typename FIELD::ValueType> output;
|
||||
@@ -202,13 +203,12 @@ public: // field access
|
||||
|
||||
private:
|
||||
static bool
|
||||
comparePos(uint64_t first, const Block& second) noexcept;
|
||||
comparePos(uint32_t first, const Block& second) noexcept;
|
||||
|
||||
private:
|
||||
mutable Block m_wire;
|
||||
mutable Block m_wire{tlv::LpPacket};
|
||||
};
|
||||
|
||||
} // namespace lp
|
||||
} // namespace ndn
|
||||
} // namespace ndn::lp
|
||||
|
||||
#endif // NDN_CXX_LP_PACKET_HPP
|
||||
Loaded 100 of 590 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user