Compare commits

...
47 Commits
Author SHA1 Message Date
SunnyQjm 6ad02f3428 feat: Add qsccp tags 2023-12-03 04:16:14 +00:00
Davide Pesavento 6d4a6536fd ci: add latest tag to docker image
Change-Id: I558a8990d67defa37dffe272305ebf5e62c30532
2023-11-18 17:05:33 -05:00
Varun Patil e58bab2e8a ci: add docker build GitHub Action
Change-Id: Ief65de7193f2aa27127bf8a49d0356f71482b12b
2023-11-18 13:09:13 -08:00
Junxiao Shi 995c411ae4 Add initial Dockerfile
Change-Id: I8d9c5a0169a9550686179a5a6c6bfb3a79f54e36
2023-11-18 16:02:05 -05:00
Davide Pesavento 49e1e87b24 Replace Boost.MPL with Mp11
Change-Id: I9e0f3cd0169a733f602ff5fc1457f63d6499387d
2023-11-11 00:45:23 -05:00
Davide Pesavento 2f46d6543e Avoid deprecated Boost.Asio interfaces
Change-Id: I00d285893ff61619f49dff8a8a55d0d0e2c309a7
2023-11-10 17:40:43 -05:00
Davide Pesavento 550d8c99ab build: require boost >= 1.71.0
Refs: #5276
Change-Id: I0f179707020fc6e0908af8aeb1d535ca3cd81410
2023-11-05 01:30:01 -04:00
Davide Pesavento e1005da0a2 docs: update list of supported platforms
Change-Id: Ic09db6ec9d84417ffc97f84a0e4bbf8dc6365955
2023-10-31 20:35:02 -04:00
Davide Pesavento 6028418380 net: NetworkMonitor: ignore AWDL interfaces on macOS
Refs: #5074
Change-Id: I5a97dfefda2a43c3dd4460e19725480bbf54835c
2023-10-26 23:01:03 -04:00
Davide Pesavento 5686c51b87 build: decouple handling of boost libs not needed by libndn-cxx
Refs: #5210
Change-Id: Ia8e3d80dd92b5e8a7bd7d79ea811332220a883ed
2023-09-07 22:08:46 -04:00
Davide Pesavento c996742bad build: use python f-strings
Change-Id: I17695613bb737ac4ba297468c5859ceb18bfdf96
2023-09-07 22:04:34 -04:00
Davide Pesavento 90d3a96dc2 encoding: simplify readVarNumber()
Change-Id: I53ee1ec43d701a95aa79d8ea9f71dd61dbe74615
2023-08-29 21:05:36 -04:00
Davide Pesavento fffdd62715 Use Boost.Operators in more places
Change-Id: I7024c3e7d4c30c99ec7a895d484f227cb60fb356
2023-08-28 22:50:43 -04:00
Junxiao Shi ce442c4c95 meta-info: prevent FreshnessPeriod overflow
refs #4997

Change-Id: I22ae27257fd79b539a8ac137f8b1871e1b988cf8
2023-08-19 23:56:54 +00:00
Davide Pesavento ee97139dcd build: update waf to version 2.0.26
Change-Id: Ica10b4eb8d8e0fd55739a5c4babc7e197aaac092
2023-08-19 01:52:06 -04:00
Davide Pesavento 03fdfb17a1 build: enable a few more compiler warnings
Refactor default-compiler-flags.py to reduce duplication

Change-Id: I059d4857ea6744ac791592c50d41a6ef8b8d60cc
2023-08-18 18:55:54 -04:00
Davide Pesavento 747cb45c16 util: add deprecated attribute to aliases documented as such
Change-Id: I334f0c3e072f773260d96f9cfe8f6029c256c41a
2023-08-16 14:44:46 -04:00
Davide Pesavento 9404892918 interest: improve code readability
And add more tests for decoding of malformed ForwardingHint

Change-Id: Ie7b043911769a0952300aa412fe7dbb893a464aa
2023-08-11 22:10:08 -04:00
Junxiao Shi 382de67df8 net: make FaceUri usable as container key
refs #4227

Change-Id: I4389fe6691ab2499c73e6ed83d4090b77fdbafca
2023-08-11 18:17:10 +00:00
Alexander Afanasyev 0af48fb516 interest: Match data to Interest regardless of FreshnessPeriod/MustBeFresh
When Data is received from the wire it should match Interest with
MustBeFresh even if the Data packet doesn't specify FreshnessPeriod.

Refs: #5270
Change-Id: I2ce4d23062f6346ebcd54e2e3e6e5de5a927e516
2023-08-09 12:26:59 -04:00
Davide Pesavento 12b8aaa9f2 build: decrease level of debug information produced by default
Refs: #5279
Change-Id: I5c96d3e58d507c5ab01e0ae79348be15e078ac9a
2023-08-06 19:18:51 -04:00
Junxiao Shi 502c4c3bd6 security: avoid ValidityPeriod under/overflow
refs #5176

Change-Id: I15f2225ea727b205798db29d14ef49a7565eb82e
2023-07-24 11:09:27 +00:00
Varun Patil f81de71486 security: make HMAC compatible with OpenSSL 3
This is a temporary workaround until the internals
can be restructured to use EVP_MAC

Refs: #5251
Change-Id: I28854177a066a753a5cbacad591ee55f5c137622
2023-07-23 14:25:03 -07:00
Davide Pesavento 67bc114aa8 util: generalize and simplify time::{to,from}UnixTimestamp()
Change-Id: I1dc94365944b8efc03f32919d32d5df0a652b672
2023-05-15 21:48:43 -04:00
Davide Pesavento 699cca4ba0 encoding: declare Block operators as hidden friends
Change-Id: Ib6a0792110cb1627e691c66bf83adf27df065c46
2023-05-12 19:50:23 -04:00
Davide Pesavento 296c3a185d interest+data: add string_view overloads for convenience
Also, explicitly declare the nullptr_t overloads as deleted, so that
users get a clear compilation error instead of a potentially confusing
"ambiguous overload" if they try to pass nullptr to these functions.

Change-Id: I399efcbd698a0d3f7e29219d21eb1a53a1d71070
2023-05-10 22:56:48 -04:00
Davide Pesavento 47ce2eed3a Refactor and modernize namespace declarations
* Completely remove inline namespace v2
 * Flatten some unnecessarily deep namespace nesting
 * Move DummyClientFace, Segmenter, SegmentFetcher to namespace ndn
 * Move all unit tests to namespace ndn::tests

Change-Id: I8bcfcf9fd669936a3277d2d5d505f765b4b05742
2023-05-10 02:37:06 -04:00
Davide Pesavento 21b7f1b379 encoding+lp+net: simplify with if constexpr
Change-Id: Ie2b45a502c59e5cb7181628e691f7aaaf7509d84
2023-04-28 23:21:02 -04:00
Davide Pesavento 581dd52b0d lp: consistently use uint32_t for TLV types
Change-Id: I880043b634476eaaafa35b49f6b3f93210ae5ecf
2023-04-24 02:10:52 -04:00
Davide Pesavento 152ef44da9 Move BOOST_CONCEPT_ASSERT to unit tests where possible
Change-Id: I0c6ae494eb7be4ab2ff422ba6d866ead9e75f4eb
2023-04-22 02:02:29 -04:00
Davide Pesavento 3fdb02f62e Use std::string_view in several APIs
Change-Id: I2c13b229162b247738cbf46d6bf71fc69d45816f
2023-04-14 04:05:08 -04:00
Davide Pesavento a3651646a9 ndnsec: stop installing deprecated command aliases
Refs: #5163
Change-Id: Ia9f705529061a2ca2cb8bcbd1a9ef1d7a5ffae31
2023-04-10 21:33:54 -04:00
Davide Pesavento 23483c76d5 name: remove deprecated functions
Change-Id: I776c34c5a81ade92354aa8d974f5f380ae2715c4
2023-04-04 14:25:36 -04:00
Davide Pesavento 0910343957 mgmt: simplify StatusDataset implementation
Change-Id: Icf21cfd8bc47333461dadd06c347b723e77f5784
2023-03-27 19:41:15 -04:00
Davide Pesavento 187e9f99b2 Adopt more C++17 features throughout the codebase
Change-Id: I31af421d8a977ba2aae23afcda289ff53230897f
2023-03-23 23:28:27 -04:00
Davide Pesavento eb87c28200 detail: stop importing std::function into ndn namespace
Change-Id: I536774e974627abbf4e8b868ebb948b90ea5d4a6
2023-03-15 21:07:02 -04:00
Davide Pesavento 869d1a3c36 util: remove obsolete backport of std::to_string
Change-Id: Ib2ba051b84032b227ce75f41e242af20b4a43c3c
2023-03-14 23:55:02 -04:00
Davide Pesavento 05ec0be21b Use inline on all namespace-scope constants defined in headers
Change-Id: Ia6e68d3fe572f6c15978c77a646ac599fa47e575
2023-03-14 21:36:01 -04:00
Davide Pesavento f6b458930f util: remove ndn::optional, use std::optional directly
Change-Id: I503e8f250e80e0ff7708070effc2e84e3b38b3b7
2023-03-13 15:12:06 -04:00
Davide Pesavento a2fbc35f12 util: remove ndn::variant, use std::variant directly
Change-Id: I374095f0f391454f3340bbf36785ccbebea2773a
2023-03-12 13:46:02 -04:00
Davide Pesavento fcd3e44028 build: switch to C++17
Change-Id: I92039300ce845de0312dceccb94c128229ed60c4
2023-03-10 18:44:11 -05:00
Davide Pesavento 762548b15e build: drop official support for Ubuntu 18.04 and macOS 10.15
Increase the minimum required version of clang on linux to 7.0 because
older versions fail to compile libstdc++'s implementation of std::variant

Change-Id: Id17d95c2869634622fc8775e085b74801a486e90
2023-03-07 14:40:22 -05:00
Davide Pesavento 02ed332ddd docs: update several URLs to point to docs.named-data.net
Change-Id: If000753573c6a50130dc3101a411b6d482ccf3ed
2023-02-23 19:40:22 -05:00
Davide Pesavento d09d52bdfa tests: fix dangling-reference warning with gcc 13
Change-Id: I73531e291d9b3146f3778c21a262d328d98eb26b
2023-02-15 14:15:06 -05:00
Davide Pesavento ae39daf4de build: switch source archive to xz compression
And a few minor README improvements

Change-Id: I667860f46b19d1ec885fd81910a116581007ac8f
2023-02-14 23:46:46 -05:00
Davide Pesavento a90b2cf762 ci: adopt reusable workflows from named-data/actions
Change-Id: Ib5b73ca2082cec8fc105a875f5c261a979db11c7
2023-02-07 17:56:06 -05:00
Davide Pesavento 535bd33223 util: add missing include for std::set
Change-Id: If18b2f6196e01949b380b41b42ae09e460310ba5
2023-01-10 02:30:12 -05:00
590 changed files with 6702 additions and 13365 deletions

No files matched your search

+6 -54
View File
@@ -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
+48
View File
@@ -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
View File
@@ -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
+3
View File
@@ -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
-4
View File
@@ -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
+1 -1
View File
@@ -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
-30
View File
@@ -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()
+83 -65
View File
@@ -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
View File
@@ -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>
-6
View File
@@ -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
View File
@@ -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
View File
@@ -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
+12 -11
View File
@@ -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 @@
[![CI](https://github.com/named-data/ndn-cxx/actions/workflows/ci.yml/badge.svg)](https://github.com/named-data/ndn-cxx/actions/workflows/ci.yml)
[![Docs](https://github.com/named-data/ndn-cxx/actions/workflows/docs.yml/badge.svg)](https://github.com/named-data/ndn-cxx/actions/workflows/docs.yml)
![Language](https://img.shields.io/badge/C%2B%2B-14-blue)
![Language](https://img.shields.io/badge/C%2B%2B-17-blue)
![Latest version](https://img.shields.io/github/v/tag/named-data/ndn-cxx?label=Latest%20version)
**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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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-->
+1 -1
View File
@@ -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
+5 -5
View File
@@ -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.
+1 -1
View File
@@ -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
^^^^^^^
+12 -12
View File
@@ -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`)
+7 -7
View File
@@ -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`)
+1 -1
View File
@@ -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`)
+1 -1
View File
@@ -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`)
+1 -1
View File
@@ -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`)
+3 -3
View File
@@ -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`)
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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>`__)
+1 -1
View File
@@ -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.
+6 -6
View File
@@ -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
+8 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+3 -14
View File
@@ -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
+3 -5
View File
@@ -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
+11 -8
View File
@@ -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
+3 -5
View File
@@ -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
+3 -7
View File
@@ -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
+3 -7
View File
@@ -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
+7 -13
View File
@@ -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
View File
@@ -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());
+55 -75
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+4 -6
View File
@@ -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
+11 -11
View File
@@ -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
+3 -5
View File
@@ -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
+3 -5
View File
@@ -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
+11 -17
View File
@@ -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
+7 -7
View File
@@ -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
+10 -12
View File
@@ -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
+5 -9
View File
@@ -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
+56 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+6 -1
View File
@@ -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
View File
@@ -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;
};
+79 -71
View File
@@ -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
+4 -4
View File
@@ -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
+20 -21
View File
@@ -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
+5 -5
View File
@@ -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);
}
+6 -8
View File
@@ -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;
};
+6 -6
View File
@@ -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);
}
+7 -10
View File
@@ -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;
};
+5 -6
View File
@@ -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);
}
+6 -8
View File
@@ -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
+16 -10
View File
@@ -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
+11 -52
View File
@@ -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*)
{
}
+35 -40
View File
@@ -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
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
{
+3 -5
View File
@@ -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
+3 -5
View File
@@ -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
+3 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+3 -5
View File
@@ -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
+3 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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