diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fb6485b2f..507fd806f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -183,7 +183,7 @@ jobs: - script: linux-checks/check-formatting image: rocstreaming/env-ubuntu - - script: linux-checks/check-doctests + - script: linux-checks/check-scons image: rocstreaming/env-ubuntu - script: linux-checks/pulseaudio-versions diff --git a/3rdparty/SConscript b/3rdparty/SConscript index 9b5dc6c12..f8985ee69 100644 --- a/3rdparty/SConscript +++ b/3rdparty/SConscript @@ -222,10 +222,9 @@ elif 'openssl' in system_dependencies: conf = Configure(env, custom_tests=env.CustomTests) if not conf.AddPkgConfigDependency('libssl', '--cflags --libs', add_prefix=ossl_prefix): - conf.env.AddManualDependency(libs=['ssl', 'crypto'], prefix=ossl_prefix) + conf.env.AddManualDependency(libs=['ssl'], prefix=ossl_prefix) - if not conf.CheckLibWithHeaderExt('ssl', 'openssl/rand.h', 'C', run=not is_crosscompiling) or \ - not conf.CheckLibWithHeaderExt('crypto', 'openssl/crypto.h', 'C', run=not is_crosscompiling): + if not conf.CheckLibWithHeaderExt('ssl', 'openssl/rand.h', 'C', run=not is_crosscompiling): env.Die("OpenSSL not found (see 'config.log' for details)") env = conf.Finish() diff --git a/SConstruct b/SConstruct index ab0f5de2e..70578dabd 100644 --- a/SConstruct +++ b/SConstruct @@ -166,7 +166,7 @@ AddOption('--enable-tests', AddOption('--enable-benchmarks', dest='enable_benchmarks', action='store_true', - help='enable benchmarks building and running (requires Google Benchmark)') + help='enable bechmarks building and running (requires Google Benchmark)') AddOption('--enable-examples', dest='enable_examples', @@ -273,7 +273,7 @@ AddOption('--macos-arch', " comma-separated list, supported values: {}".format( ', '.join(["'{}'".format(s) for s in supported_macos_archs])) + " (default is current OS arch, pass multiple values" - " or 'all' for universal binaries)")) + " or 'all' for univeral binaries)")) AddOption('--build-3rdparty', dest='build_3rdparty', @@ -407,12 +407,12 @@ for p in ['bin', clean_all += [env.DeleteFile(f)] env.AlwaysBuild(env.Alias('clean', [], clean_all)) -env.AlwaysBuild(env.Alias('clean_build', [], clean_build)) -env.AlwaysBuild(env.Alias('clean_docs', [], clean_doc)) +env.AlwaysBuild(env.Alias('cleanbuild', [], clean_build)) +env.AlwaysBuild(env.Alias('cleandocs', [], clean_doc)) -if set(COMMAND_LINE_TARGETS).intersection(['clean', 'clean_build', 'clean_docs']) or \ +if set(COMMAND_LINE_TARGETS).intersection(['clean', 'cleanbuild', 'cleandocs']) or \ env.GetOption('clean'): - if set(COMMAND_LINE_TARGETS) - set(['clean', 'clean_build', 'clean_docs']): + if set(COMMAND_LINE_TARGETS) - set(['clean', 'cleanbuild', 'cleandocs']): env.Die("combining 'clean*' targets with other targets is not allowed") if env.GetOption('clean'): if clean_all: @@ -444,13 +444,13 @@ doc_env = env.DeepClone() doc_env.SConscript('docs/SConscript', duplicate=0, exports='doc_env') -# run python doctests -env.AlwaysBuild(env.Alias('doctest', [], [ - env.DocTest('#scripts/scons_helpers/build-3rdparty.py'), +# run scons self-test +env.AlwaysBuild(env.Alias('selftest', [], [ + env.SelfTest(), ])) # exit early if there is nothing to build -non_build_targets = ['fmt', 'docs', 'sphinx', 'doxygen', 'doctest'] +non_build_targets = ['fmt', 'docs', 'sphinx', 'doxygen', 'selftest'] if set(COMMAND_LINE_TARGETS) \ and set(COMMAND_LINE_TARGETS).intersection(non_build_targets) == set(COMMAND_LINE_TARGETS): Return() @@ -522,15 +522,6 @@ if not meta.compiler_ver: env.Die("can't detect compiler version for compiler '{}'", '-'.join([s for s in [meta.toolchain, meta.compiler] if s])) -if GetOption('compiler') and env.HasArgument('CXX'): - detected_compiler = env.ParseCompilerType(env['CXX']) - if detected_compiler and detected_compiler != meta.compiler: - env.Warn("forcing compiler '{}-{}' from '--compiler={}' option,"+ - " but detected compiler '{}' from 'CXX={}' variable", - meta.compiler, '.'.join(map(str, meta.compiler_ver)), - GetOption('compiler'), - detected_compiler, env['CXX']) - conf = Configure(env, custom_tests=env.CustomTests) if meta.compiler == 'clang': @@ -670,10 +661,6 @@ if meta.platform == 'darwin': conf.FindTool('LIPO', [''], [('lipo', None)], required=False) conf.FindTool('INSTALL_NAME_TOOL', [''], [('install_name_tool', None)], required=False) -if meta.compiler == 'gcc' or meta.compiler == 'clang': - if conf.CheckLib('atomic'): - env.AddManualDependency(libs=['atomic']) # explicitly needed by libcrypto (openssl) - meta.c11_support = False if not GetOption('disable_c11'): if meta.compiler == 'gcc': diff --git a/docs/man/roc-copy.1 b/docs/man/roc-copy.1 index 9ddb70e7c..cdbf81358 100644 --- a/docs/man/roc-copy.1 +++ b/docs/man/roc-copy.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "ROC-COPY" "1" "2025" "Roc Toolkit 0.4" "Roc Toolkit" +.TH "ROC-COPY" "1" "2024" "Roc Toolkit 0.4" "Roc Toolkit" .SH NAME roc-copy \- copy local audio .SH SYNOPSIS @@ -235,6 +235,6 @@ Please report any bugs found via GitHub (\fI\%https://github.com/roc\-streaming/ .sp See authors page on the website for a list of maintainers and contributors (\fI\%https://roc\-streaming.org/toolkit/docs/about_project/authors.html\fP). .SH COPYRIGHT -2025, Roc Streaming authors +2024, Roc Streaming authors .\" Generated by docutils manpage writer. . diff --git a/docs/man/roc-recv.1 b/docs/man/roc-recv.1 index 1c3d9fbab..4c5a8c0bc 100644 --- a/docs/man/roc-recv.1 +++ b/docs/man/roc-recv.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "ROC-RECV" "1" "2025" "Roc Toolkit 0.4" "Roc Toolkit" +.TH "ROC-RECV" "1" "2024" "Roc Toolkit 0.4" "Roc Toolkit" .SH NAME roc-recv \- receive real-time audio .SH SYNOPSIS @@ -828,6 +828,6 @@ Please report any bugs found via GitHub (\fI\%https://github.com/roc\-streaming/ .sp See authors page on the website for a list of maintainers and contributors (\fI\%https://roc\-streaming.org/toolkit/docs/about_project/authors.html\fP). .SH COPYRIGHT -2025, Roc Streaming authors +2024, Roc Streaming authors .\" Generated by docutils manpage writer. . diff --git a/docs/man/roc-send.1 b/docs/man/roc-send.1 index a45494d41..9776beca3 100644 --- a/docs/man/roc-send.1 +++ b/docs/man/roc-send.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "ROC-SEND" "1" "2025" "Roc Toolkit 0.4" "Roc Toolkit" +.TH "ROC-SEND" "1" "2024" "Roc Toolkit 0.4" "Roc Toolkit" .SH NAME roc-send \- send real-time audio .SH SYNOPSIS @@ -760,6 +760,6 @@ Please report any bugs found via GitHub (\fI\%https://github.com/roc\-streaming/ .sp See authors page on the website for a list of maintainers and contributors (\fI\%https://roc\-streaming.org/toolkit/docs/about_project/authors.html\fP). .SH COPYRIGHT -2025, Roc Streaming authors +2024, Roc Streaming authors .\" Generated by docutils manpage writer. . diff --git a/docs/sphinx/building/developer_cookbook.rst b/docs/sphinx/building/developer_cookbook.rst index cfaeedab4..c7c089dbb 100644 --- a/docs/sphinx/building/developer_cookbook.rst +++ b/docs/sphinx/building/developer_cookbook.rst @@ -261,10 +261,10 @@ Clean build results except third-parties and documentation: .. code:: - $ scons -Q clean_build + $ scons -Q cleanbuild Clean only built documentation: .. code:: - $ scons -Q clean_docs + $ scons -Q cleandocs diff --git a/docs/sphinx/building/scons_options.rst b/docs/sphinx/building/scons_options.rst index 88f90c868..2a7026244 100644 --- a/docs/sphinx/building/scons_options.rst +++ b/docs/sphinx/building/scons_options.rst @@ -38,67 +38,44 @@ Options -n dry run -j N, --jobs=N allow N parallel jobs at once - --prefix=PREFIX installation prefix, '/usr' by default - --bindir=BINDIR path to the binary installation directory (where to install Roc command-line - tools), '/bin' by default - --libdir=LIBDIR path to the library installation directory (where to install Roc library), - auto-detected by default - --incdir=INCDIR path to the headers installation directory (where to install Roc headers), - '/include' by default - --mandir=MANDIR path to the manuals installation directory (where to install Roc manual - pages), '/share/man/man1' by default - --build=BUILD system name where Roc is being compiled, e.g. 'x86_64-pc-linux-gnu', - auto-detected by default - --host=HOST system name where Roc will run, e.g. 'arm-linux-gnueabihf', auto-detected by - default - --platform=PLATFORM platform name where Roc will run, supported values: empty (detect from host), - 'linux', 'unix', 'darwin', 'android' - --compiler=COMPILER compiler name and optional version, e.g. 'gcc-4.9', supported names: - empty (detect what available), 'clang', 'gcc', 'cc' - --compiler-launcher=COMPILER_LAUNCHER - optional launching tool for c and c++ compilers, e.g. 'ccache' - --sanitizers=SANITIZERS list of gcc/clang sanitizers, supported names: empty (no sanitizers), - 'all', 'undefined', 'address' - --enable-debug enable debug build for Roc - --enable-debug-3rdparty enable debug build for 3rdparty libraries - --enable-werror treat warnings as errors - --enable-static enable building static library - --disable-shared disable building shared library - --disable-tools disable tools building - --enable-tests enable tests building and running (requires CppUTest) - --enable-benchmarks enable benchmarks building and running (requires Google Benchmark) - --enable-examples enable examples building - --enable-doxygen enable Doxygen documentation generation - --enable-sphinx enable Sphinx documentation generation - --disable-c11 disable C11 support - --disable-soversion don't write version into the shared library and don't create version symlinks - --disable-openfec disable OpenFEC support required for FEC codes - --disable-speexdsp disable SpeexDSP support for resampling - --disable-sox disable SoX support in tools - --disable-sndfile disable sndfile support in tools - --disable-openssl disable OpenSSL support required for DTLS and SRTP - --disable-libunwind disable libunwind support required for printing backtrace - --disable-libuuid disable libuuid support for reliable UUID generation - --disable-alsa disable ALSA support in tools - --disable-pulseaudio disable PulseAudio support in tools - --with-openfec-includes=WITH_OPENFEC_INCLUDES - path to the directory with OpenFEC headers (it should contain lib_common and - lib_stable subdirectories) - --with-includes=WITH_INCLUDES - additional include search path, may be used multiple times - --with-libraries=WITH_LIBRARIES - additional library search path, may be used multiple times - --macos-platform=MACOS_PLATFORM - macOS target platform, e.g. 10.12, (default is current OS version) - --macos-arch=MACOS_ARCH macOS target architecture(s), comma-separated list, supported values: 'all', - 'x86_64', 'arm64' (default is current OS arch, pass multiple values or - 'all' for universal binaries) - --build-3rdparty=BUILD_3RDPARTY - download and build specified 3rdparty libraries, comma-separated list of - library names and optional versions, e.g. 'libuv:1.4.2,openfec' - --override-targets=OVERRIDE_TARGETS - override targets to use, pass a comma-separated list of target names, e.g. - 'pc,posix,posix_ext,gnu,libuv,openfec,...' +--prefix=PREFIX installation prefix, '/usr' by default +--bindir=BINDIR path to the binary installation directory (where to install Roc command-line tools), '/bin' by default +--libdir=LIBDIR path to the library installation directory (where to install Roc library), auto-detected by default +--incdir=INCDIR path to the headers installation directory (where to install Roc headers), '/include' by default +--mandir=MANDIR path to the manuals installation directory (where to install Roc manual pages), '/share/man/man1' by default +--build=BUILD system name where Roc is being compiled, e.g. 'x86_64-pc-linux-gnu', auto-detected by default +--host=HOST system name where Roc will run, e.g. 'arm-linux-gnueabihf', auto-detected by default +--platform=PLATFORM platform name where Roc will run, supported values: empty (detect from host), 'linux', 'unix', 'darwin', 'android' +--compiler=COMPILER compiler name and optional version, e.g. 'gcc-4.9', supported names: empty (detect what available), 'clang', 'gcc', 'cc' +--compiler-launcher=COMPILER_LAUNCHER optional launching tool for c and c++ compilers, e.g. 'ccache' +--sanitizers=SANITIZERS list of gcc/clang sanitizers, supported names: empty (no sanitizers), 'all', 'undefined', 'address' +--enable-debug enable debug build for Roc +--enable-debug-3rdparty enable debug build for 3rdparty libraries +--enable-werror treat warnings as errors +--enable-static enable building static library +--disable-shared disable building shared library +--disable-tools disable tools building +--enable-tests enable tests building and running (requires CppUTest) +--enable-benchmarks enable bechmarks building and running (requires Google Benchmark) +--enable-examples enable examples building +--enable-doxygen enable Doxygen documentation generation +--enable-sphinx enable Sphinx documentation generation +--disable-c11 disable C11 support +--disable-soversion don't write version into the shared library and don't create version symlinks +--disable-openfec disable OpenFEC support required for FEC codes +--disable-speexdsp disable SpeexDSP support for resampling +--disable-sox disable SoX support in tools +--disable-openssl disable OpenSSL support required for DTLS and SRTP +--disable-libunwind disable libunwind support required for printing backtrace +--disable-alsa disable ALSA support in tools +--disable-pulseaudio disable PulseAudio support in tools +--with-openfec-includes=WITH_OPENFEC_INCLUDES path to the directory with OpenFEC headers (it should contain lib_common and lib_stable subdirectories) +--with-includes=WITH_INCLUDES additional include search path, may be used multiple times +--with-libraries=WITH_LIBRARIES additional library search path, may be used multiple times +--macos-platform=MACOS_PLATFORM macOS target platform, e.g. 10.12, (default is current OS version) +--macos-arch=MACOS_ARCH macOS target architecture(s), comma-separated list, supported values: 'all', 'x86_64', 'arm64' (default is current OS arch, pass multiple values or 'all' for univeral binaries) +--build-3rdparty=BUILD_3RDPARTY download and build specified 3rdparty libraries, comma-separated list of library names and optional versions, e.g. 'libuv:1.4.2,openfec' +--override-targets=OVERRIDE_TARGETS override targets to use, pass a comma-separated list of target names, e.g. 'pc,posix,posix_ext,gnu,libuv,openfec,...' Variables ========= @@ -131,14 +108,14 @@ Variables Targets ======= -`omitted` or ``.`` - build everything (including documentation, see ``docs`` target) +`omitted` + build everything ``test`` - build everything, then run tests + build everything and run tests ``bench`` - build everything, then run benchmarks + build everything and run benchmarks ``clean`` full clean, including build results, downloaded third-parties, generated documentation, and scons database @@ -150,16 +127,16 @@ Targets remove only generated documentation ``install`` - install build results into the system or ``DESTDIR`` + install build results into the system ``uninstall`` - remove build results from the system or ``DESTDIR`` + remove build results from the system ``fmt`` format source code (requires clang-format) ``docs`` - build documentation, includes ``doxygen`` target if enabled with ``--enable-doxygen`` and ``sphinx`` target if enabled with ``--enable-sphinx`` + build website (includes ``doxygen`` and ``sphinx`` targets) ``doxygen`` build doxygen documentation (requires doxygen and graphviz) @@ -167,9 +144,6 @@ Targets ``sphinx`` build sphinx documentation (requires doxygen, sphinx-build, and breathe-apidoc) -``doctest`` - run python doctests from scripts (useful when you're updating scripts) - ``{module}`` build specific module, e.g. ``roc_pipeline`` diff --git a/scripts/ci_checks/docker.sh b/scripts/ci_checks/docker.sh index 69d344500..3c08f19ab 100755 --- a/scripts/ci_checks/docker.sh +++ b/scripts/ci_checks/docker.sh @@ -1,12 +1,5 @@ #!/usr/bin/env bash -# -# This script can be run locally by user 'bob' like this: -# -# DOCKER_UID="$(id -u bob)" DOCKER_GID="$(id -g bob)" ./scripts/ci_checks/docker.sh ... -# -# (the full command line with exact arguments to docker.sh can be taken from CI) - -set -eux -o pipefail +set -euxo pipefail if [ -z "${CI:-}" ]; then opts=-ti @@ -14,14 +7,9 @@ else opts=-t fi -user="${DOCKER_UID:-"$UID"}" -if [ -n "${DOCKER_GID:-}" ]; then - user="$user:$DOCKER_GID" -fi - docker run --rm ${opts} \ --cap-add SYS_PTRACE \ - -u "$user" \ + -u "${UID}" \ -v "$(pwd)":/opt/roc \ -w /opt/roc \ -e CI="${CI:-}" \ diff --git a/scripts/ci_checks/linux-checks/check-doctests.sh b/scripts/ci_checks/linux-checks/check-scons.sh similarity index 68% rename from scripts/ci_checks/linux-checks/check-doctests.sh rename to scripts/ci_checks/linux-checks/check-scons.sh index b3a2d0d89..959ec99e7 100755 --- a/scripts/ci_checks/linux-checks/check-doctests.sh +++ b/scripts/ci_checks/linux-checks/check-scons.sh @@ -2,4 +2,4 @@ set -euo pipefail -scons -Q doctest +scons -Q selftest diff --git a/scripts/rgh.py b/scripts/rgh.py index 4f531cc76..16924949d 100755 --- a/scripts/rgh.py +++ b/scripts/rgh.py @@ -5,7 +5,6 @@ import argparse import colorama import functools -import itertools import json import os import os.path @@ -18,7 +17,6 @@ import time DRY_RUN = False -TOKEN = None def error(message): print(f'{Fore.RED}{Style.BRIGHT}error:{Style.RESET_ALL} {message}', file=sys.stderr) @@ -28,29 +26,15 @@ def print_cmd(cmd): pretty = ' '.join(['"'+c+'"' if ' ' in c else c for c in map(str, cmd)]) print(f'{Fore.YELLOW}{pretty}{Style.RESET_ALL}') -def find_token(machine, login): - path = os.path.expanduser('~/.authinfo') - if not os.path.exists(path): - return - with open(path) as fp: - for line in fp: - it = iter(line.split()) - entry = dict(zip(it, it)) - if entry.get('machine') == machine and entry.get('login') == login: - return entry.get('password') - def run_cmd(cmd, input=None, env=None, retry_fn=None): cmd = [str(c) for c in cmd] - environ = os.environ.copy() - if TOKEN: - environ['GH_TOKEN'] = TOKEN - if env: - environ.update(env) - if input: input = input.encode() - + if env: + e = os.environ.copy() + e.update(env) + env = e stdout = None if retry_fn: stdout = subprocess.PIPE @@ -62,7 +46,7 @@ def run_cmd(cmd, input=None, env=None, retry_fn=None): print_cmd(cmd) if DRY_RUN: return - proc = subprocess.run(cmd, input=input, stdout=stdout, env=environ, check=True) + proc = subprocess.run(cmd, input=input, stdout=stdout, env=env, check=True) if stdout is not None: output = proc.stdout.decode() print(output, end='') @@ -82,7 +66,7 @@ def run_cmd(cmd, input=None, env=None, retry_fn=None): def enter_worktree(): def random_dir(): while True: - path = '/tmp/rgh-' + ''.join(random.choice(string.ascii_lowercase + string.digits) + path = '/tmp/rgh_' + ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(8)) if not os.path.exists(path): return path @@ -167,38 +151,6 @@ def guess_issue(org, repo, text): return None -def make_prefix_suffix_regexp(org, repo, is_prefix): - kv_rx = [ - "issue", - "ticket", - "task", - ] - nm_rx = [ - r"gh-[0-9]+", - r"#?[0-9]+", - f"{org}/[^ ]+", - f"{repo}#[^ ]+", - ] - - prod_rx = nm_rx[:] - for kv, nm in itertools.product(kv_rx, nm_rx): - prod_rx.append(f"{kv}\\s+{nm}") - - sep = r"[\[\]():{}]" - - rx = f"\\s*{sep}?\\s*({'|'.join(prod_rx)})\\s*{sep}?\\s*" - - if is_prefix: - return f"^({rx})?" - else: - return f"(({rx})?\\.?\\s*$)" - -def make_prefix_regexp(org, repo): - return make_prefix_suffix_regexp(org, repo, is_prefix=True) - -def make_suffix_regexp(org, repo): - return make_prefix_suffix_regexp(org, repo, is_prefix=False) - # format prefix for commit message def make_prefix(org, repo, issue_link): if not issue_link: @@ -214,8 +166,9 @@ def make_prefix(org, repo, issue_link): # format commit message def make_message(org, repo, issue_link, pr_title): - pr_title = re.sub(make_prefix_regexp(org, repo), '', pr_title, flags=re.IGNORECASE) - pr_title = re.sub(make_suffix_regexp(org, repo), '', pr_title, flags=re.IGNORECASE) + pr_title = re.sub(r'^([Ii]ssue\s+\d+(:\s*)?)', '', pr_title) + pr_title = re.sub(r'\s*\(?#\d+\)?$', '', pr_title) + pr_title = re.sub(r'\.$', '', pr_title) if issue_link: return '{}: {}'.format( @@ -508,7 +461,7 @@ def verify_pr(org, repo, pr_number, issue_number, issue_miletsone, no_issue, no_ for action_name, action_result in query_pr_actions(org, repo, pr_number): if action_result != 'success': error("can't proceed on pr with failed checks\n" - "use --ignore-actions to proceed anyway") + "use --no-checks to proceed anyway") # checkout PR's branch def checkout_pr(org, repo, pr_number): @@ -688,8 +641,8 @@ def reword_pr_commits(org, repo, pr_number, title, no_issue): f" -e '1s,^.*$,{commit_prefix}{title},'" else: sed = f"sed -r"+\ - f" -e '1s,{make_prefix_regexp(org, repo)},{commit_prefix},I'"+\ - f" -e '1s,{make_suffix_regexp(org, repo)},,I'" + f" -e '1s,^(gh-[0-9]+:? *|#[0-9]+:? *|{org}/[^ ]+ *|[Ii]ssue *[0-9]+:? *)?,{commit_prefix},'"+\ + f" -e '1s,\s*\(?#[0-9]+\)?$,,'" run_cmd([ 'git', 'filter-branch', '-f', '--msg-filter', sed, @@ -780,8 +733,10 @@ def stb_rebase(base_branch): parser = argparse.ArgumentParser(prog='rgh.py') common_parser = argparse.ArgumentParser(add_help=False) -common_parser.add_argument('--org', default='roc-streaming', help='github org') -common_parser.add_argument('--repo', default='roc-toolkit', help='github repo') +common_parser.add_argument('--org', default='roc-streaming', + help='github org') +common_parser.add_argument('--repo', default='roc-toolkit', + help='github repo') subparsers = parser.add_subparsers(dest='command') @@ -829,11 +784,6 @@ def stb_rebase(base_branch): if hasattr(args, 'dry_run'): DRY_RUN = args.dry_run -if not os.environ.get('GH_TOKEN'): - token = find_token('api.github.com', 'rocstreaming-bot') - if token: - TOKEN = token - colorama.init() if args.command == 'stb_rebase': diff --git a/scripts/scons_helpers/build-3rdparty.py b/scripts/scons_helpers/build-3rdparty.py index 830ef2fb1..19f8e0628 100644 --- a/scripts/scons_helpers/build-3rdparty.py +++ b/scripts/scons_helpers/build-3rdparty.py @@ -1,6 +1,7 @@ from __future__ import print_function import argparse +import doctest import fileinput import fnmatch import glob @@ -984,642 +985,648 @@ def die(text, *args): exit(1) # -# Don't proceed if loaded as module from doctests.py. +# Parse command-line options. # -if __name__ == '__main__': +if '--self-test' in sys.argv: + failures, total = doctest.testmod(report=True) - # - # Parse command-line options. - # + if failures == 0: + print('OK: {} tests passed'.format(total)) + exit(0) + else: + exit(1) - parser = argparse.ArgumentParser(description='build third-party packages') +parser = argparse.ArgumentParser(description='build third-party packages') - parser.add_argument('--root-dir', dest='root_dir', type=str, required=True, - help='path to project root') +parser.add_argument('--self-test', action='store_true', + help='run doctests and exit') - parser.add_argument('--work-dir', dest='work_dir', type=str, required=True, - help='path to working directory') +parser.add_argument('--root-dir', dest='root_dir', type=str, required=True, + help='path to project root') - parser.add_argument('--dist-dir', dest='dist_dir', type=str, required=True, - help='path to vendored distfiles directory') +parser.add_argument('--work-dir', dest='work_dir', type=str, required=True, + help='path to working directory') - parser.add_argument('--build', dest='build', type=str, required=True, - help='system when package is built (e.g. x86_64-pc-linux-gnu)') +parser.add_argument('--dist-dir', dest='dist_dir', type=str, required=True, + help='path to vendored distfiles directory') - parser.add_argument('--host', dest='host', type=str, required=True, - help='system when package will run (e.g. aarch64-linux-gnu)') +parser.add_argument('--build', dest='build', type=str, required=True, + help='system when package is built (e.g. x86_64-pc-linux-gnu)') - parser.add_argument('--toolchain', dest='toolchain', type=str, - help='toolchain prefix (e.g. aarch64-linux-gnu)') +parser.add_argument('--host', dest='host', type=str, required=True, + help='system when package will run (e.g. aarch64-linux-gnu)') - parser.add_argument('--variant', dest='variant', type=str, required=True, - help='build variant', choices=['debug', 'release']) +parser.add_argument('--toolchain', dest='toolchain', type=str, + help='toolchain prefix (e.g. aarch64-linux-gnu)') - parser.add_argument('--package', dest='package', type=str, required=True, - help='package name and version (e.g. openssl-3.0.7-rc1)') +parser.add_argument('--variant', dest='variant', type=str, required=True, + help='build variant', choices=['debug', 'release']) - parser.add_argument('--deps', dest='deps', type=str, nargs='*', - help='package dependencies (should be built previously)') +parser.add_argument('--package', dest='package', type=str, required=True, + help='package name and version (e.g. openssl-3.0.7-rc1)') - parser.add_argument('--vars', dest='vars', type=str, nargs='*', - help='environment variables (e.g. CC=gcc CXX=g++ ...)') +parser.add_argument('--deps', dest='deps', type=str, nargs='*', + help='package dependencies (should be built previously)') - parser.add_argument('--android-platform', dest='android_platform', type=str, - help='android target platform version') +parser.add_argument('--vars', dest='vars', type=str, nargs='*', + help='environment variables (e.g. CC=gcc CXX=g++ ...)') - parser.add_argument('--macos-platform', dest='macos_platform', type=str, - help='macos target platform version') +parser.add_argument('--android-platform', dest='android_platform', type=str, + help='android target platform version') - parser.add_argument('--macos-arch', dest='macos_arch', type=str, nargs='*', - help='macos target architecture(s)') +parser.add_argument('--macos-platform', dest='macos_platform', type=str, + help='macos target platform version') - args = parser.parse_args() +parser.add_argument('--macos-arch', dest='macos_arch', type=str, nargs='*', + help='macos target architecture(s)') - # - # Setup context. - # +args = parser.parse_args() - ctx = Context() +# +# Setup context. +# - ctx.pkg = args.package - ctx.pkg_name, ctx.pkg_ver = parse_dep(args.package) - ctx.pkg_ver_major, ctx.pkg_ver_minor, ctx.pkg_ver_patch = parse_ver(ctx.pkg_ver, count=3) - ctx.pkg_deps = args.deps or [] +ctx = Context() - ctx.build = args.build - ctx.host = args.host - ctx.toolchain = args.toolchain or '' - ctx.variant = args.variant - ctx.android_platform = args.android_platform - ctx.macos_platform = args.macos_platform - ctx.macos_arch = args.macos_arch +ctx.pkg = args.package +ctx.pkg_name, ctx.pkg_ver = parse_dep(args.package) +ctx.pkg_ver_major, ctx.pkg_ver_minor, ctx.pkg_ver_patch = parse_ver(ctx.pkg_ver, count=3) +ctx.pkg_deps = args.deps or [] - ctx.unparsed_env = args.vars or [] - ctx.env = parse_env(args.vars) +ctx.build = args.build +ctx.host = args.host +ctx.toolchain = args.toolchain or '' +ctx.variant = args.variant +ctx.android_platform = args.android_platform +ctx.macos_platform = args.macos_platform +ctx.macos_arch = args.macos_arch - os.chdir(args.root_dir) +ctx.unparsed_env = args.vars or [] +ctx.env = parse_env(args.vars) - ctx.root_dir = os.path.abspath('.') - ctx.work_dir = os.path.abspath(args.work_dir) - ctx.dist_dir = os.path.abspath(args.dist_dir) +os.chdir(args.root_dir) - ctx.pkg_dir = os.path.join(ctx.work_dir, ctx.pkg) +ctx.root_dir = os.path.abspath('.') +ctx.work_dir = os.path.abspath(args.work_dir) +ctx.dist_dir = os.path.abspath(args.dist_dir) - ctx.pkg_src_dir = os.path.join(ctx.pkg_dir, 'src') - ctx.pkg_bin_dir = os.path.join(ctx.pkg_dir, 'bin') - ctx.pkg_lib_dir = os.path.join(ctx.pkg_dir, 'lib') - ctx.pkg_inc_dir = os.path.join(ctx.pkg_dir, 'include') - ctx.pkg_rpath_dir = os.path.join(ctx.pkg_dir, 'rpath') +ctx.pkg_dir = os.path.join(ctx.work_dir, ctx.pkg) - ctx.log_file = os.path.join(ctx.pkg_dir, 'build.log') - ctx.commit_file = os.path.join(ctx.pkg_dir, 'commit') +ctx.pkg_src_dir = os.path.join(ctx.pkg_dir, 'src') +ctx.pkg_bin_dir = os.path.join(ctx.pkg_dir, 'bin') +ctx.pkg_lib_dir = os.path.join(ctx.pkg_dir, 'lib') +ctx.pkg_inc_dir = os.path.join(ctx.pkg_dir, 'include') +ctx.pkg_rpath_dir = os.path.join(ctx.pkg_dir, 'rpath') - ctx.prefer_cmake = bool(args.macos_platform or args.android_platform) +ctx.log_file = os.path.join(ctx.pkg_dir, 'build.log') +ctx.commit_file = os.path.join(ctx.pkg_dir, 'commit') - # - # Build package. - # - - rmpath(ctx.commit_file) - mkpath(ctx.pkg_src_dir) +ctx.prefer_cmake = bool(args.macos_platform or args.android_platform) - changedir(ctx, ctx.pkg_dir) +# +# Build package. +# - if ctx.pkg_name == 'libuv': - download( - ctx, - 'https://dist.libuv.org/dist/v{ctx.pkg_ver}/libuv-v{ctx.pkg_ver}.tar.gz', - 'libuv-v{ctx.pkg_ver}.tar.gz') - unpack( - ctx, - 'libuv-v{ctx.pkg_ver}.tar.gz', - 'libuv-v{ctx.pkg_ver}') - changedir(ctx, 'src/libuv-v{ctx.pkg_ver}') - if ctx.prefer_cmake: - mkpath('build') - changedir(ctx, 'build') - execute_cmake(ctx, '..', args=[ - '-DLIBUV_BUILD_TESTS=OFF', - ]) - execute_cmake_build(ctx) - if os.path.isfile('libuv_a.a'): - shutil.copy('libuv_a.a', '../libuv.a') - else: - shutil.copy('libuv.a', '../libuv.a') - changedir(ctx, '..') - else: - subst_files(ctx, 'src/unix/core.c', ' dup3', ' uv__dup3') - execute(ctx, './autogen.sh') - execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( - host=ctx.toolchain, - vars=format_vars(ctx), - flags=format_flags(ctx), - opts=' '.join([ - '--with-pic', - '--enable-static', - ]))) - execute_make(ctx) - shutil.copy('.libs/libuv.a', 'libuv.a') - install_tree(ctx, 'include', ctx.pkg_inc_dir) - install_files(ctx, 'libuv.a', ctx.pkg_lib_dir) - elif ctx.pkg_name == 'libatomic_ops': - download( - ctx, - 'https://github.com/ivmai/libatomic_ops/releases/download/' - 'v{ctx.pkg_ver}/libatomic_ops-{ctx.pkg_ver}.tar.gz', - 'libatomic_ops-{ctx.pkg_ver}.tar.gz') - unpack(ctx, - 'libatomic_ops-{ctx.pkg_ver}.tar.gz', - 'libatomic_ops-{ctx.pkg_ver}') - changedir(ctx, 'src/libatomic_ops-{ctx.pkg_ver}') - execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( - host=ctx.toolchain, - vars=format_vars(ctx), - flags=format_flags(ctx, cflags='-fPIC'), - opts=' '.join([ - '--disable-docs', - '--disable-shared', - '--enable-static', - ]))) - execute_make(ctx) - install_tree(ctx, 'src', ctx.pkg_inc_dir, include=['*.h']) - install_files(ctx, 'src/.libs/libatomic_ops.a', ctx.pkg_lib_dir) - elif ctx.pkg_name == 'libunwind': - download( - ctx, - 'http://download.savannah.nongnu.org/releases/libunwind/' - 'libunwind-{ctx.pkg_ver}.tar.gz', - 'libunwind-{ctx.pkg_ver}.tar.gz') - unpack(ctx, - 'libunwind-{ctx.pkg_ver}.tar.gz', - 'libunwind-{ctx.pkg_ver}') - changedir(ctx, 'src/libunwind-{ctx.pkg_ver}') - execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( - host=ctx.toolchain, - vars=format_vars(ctx), - flags=format_flags(ctx, cflags='-fcommon -fPIC'), - opts=' '.join([ - '--disable-coredump', - '--disable-minidebuginfo', - '--disable-ptrace', - '--disable-setjmp', - '--disable-shared', - '--enable-static', - ]))) - execute_make(ctx) - install_files(ctx, 'include/*.h', ctx.pkg_inc_dir) - install_files(ctx, 'src/.libs/libunwind.a', ctx.pkg_lib_dir) - elif ctx.pkg_name == 'libuuid': - download( - ctx, - 'https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/'+ - 'v{ctx.pkg_ver_major}.{ctx.pkg_ver_minor}/util-linux-{ctx.pkg_ver}.tar.gz', - 'util-linux-{ctx.pkg_ver}.tar.gz') - unpack(ctx, - 'util-linux-{ctx.pkg_ver}.tar.gz', - 'util-linux-{ctx.pkg_ver}') - changedir(ctx, 'src/util-linux-{ctx.pkg_ver}') - execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( - host=ctx.toolchain, - vars=format_vars(ctx), - flags=format_flags(ctx, cflags='-fcommon -fPIC'), - opts=' '.join([ - '--disable-year2038', - '--disable-all-programs', - '--enable-libuuid', - ]))) - execute_make(ctx) - install_files(ctx, 'libuuid/src/uuid.h', ctx.pkg_inc_dir) - install_files(ctx, '.libs/libuuid.a', ctx.pkg_lib_dir) - elif ctx.pkg_name == 'openfec': - if ctx.variant == 'debug': - setattr(ctx, 'res_dir', 'bin/Debug') - else: - setattr(ctx, 'res_dir', 'bin/Release') - download( - ctx, - 'https://github.com/roc-streaming/openfec/archive/v{ctx.pkg_ver}.tar.gz', - 'openfec_v{ctx.pkg_ver}.tar.gz') - unpack(ctx, - 'openfec_v{ctx.pkg_ver}.tar.gz', - 'openfec-{ctx.pkg_ver}') - changedir(ctx, 'src/openfec-{ctx.pkg_ver}') +rmpath(ctx.commit_file) +mkpath(ctx.pkg_src_dir) + +changedir(ctx, ctx.pkg_dir) + +if ctx.pkg_name == 'libuv': + download( + ctx, + 'https://dist.libuv.org/dist/v{ctx.pkg_ver}/libuv-v{ctx.pkg_ver}.tar.gz', + 'libuv-v{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + 'libuv-v{ctx.pkg_ver}.tar.gz', + 'libuv-v{ctx.pkg_ver}') + changedir(ctx, 'src/libuv-v{ctx.pkg_ver}') + if ctx.prefer_cmake: mkpath('build') changedir(ctx, 'build') execute_cmake(ctx, '..', args=[ - '-DBUILD_STATIC_LIBS=ON', - '-DDEBUG:STRING=%s' % ('ON' if ctx.variant == 'debug' else 'OFF'), + '-DLIBUV_BUILD_TESTS=OFF', ]) execute_cmake_build(ctx) - changedir(ctx, '..') - install_tree(ctx, 'src', ctx.pkg_inc_dir, include=['*.h']) - install_files(ctx, '{ctx.res_dir}/libopenfec.a', ctx.pkg_lib_dir) - elif ctx.pkg_name == 'openssl': - download( - ctx, - 'https://www.openssl.org/source/openssl-{ctx.pkg_ver}.tar.gz', - 'openssl-{ctx.pkg_ver}.tar.gz') - unpack( - ctx, - 'openssl-{ctx.pkg_ver}.tar.gz', - 'openssl-{ctx.pkg_ver}') - changedir(ctx, 'src/openssl-{ctx.pkg_ver}') - # see https://github.com/openssl/openssl/blob/master/INSTALL.md#configuration-options - execute(ctx, '{vars} {flags} ./Configure {platform} {variant} {options}'.format( - vars=format_vars(ctx, disable_launcher=True), - flags=format_flags(ctx), - platform=detect_openssl_platform(ctx.host), - variant='--debug' if ctx.variant == 'debug' else '--release', - options=' '.join([ - 'no-asan', - 'no-buildtest-c++', - 'no-external-tests', - 'no-fuzz-afl', - 'no-fuzz-libfuzzer', - 'no-shared', - 'no-tests', - 'no-ubsan', - 'no-ui-console', - 'no-unit-test', - ]))) - execute_make(ctx) - install_tree(ctx, 'include', ctx.pkg_inc_dir) - install_files(ctx, 'libssl.a', ctx.pkg_lib_dir) - install_files(ctx, 'libcrypto.a', ctx.pkg_lib_dir) - elif ctx.pkg_name == 'speexdsp': - if ctx.pkg_ver.split('.', 1) > ['1', '2'] and ( - not re.match('^1.2[a-z]', ctx.pkg_ver) or ctx.pkg_ver == '1.2rc3'): - setattr(ctx, 'pkg_repo', 'speexdsp') + if os.path.isfile('libuv_a.a'): + shutil.copy('libuv_a.a', '../libuv.a') else: - setattr(ctx, 'pkg_repo', 'speex') - download( - ctx, - 'http://downloads.xiph.org/releases/speex/{ctx.pkg_repo}-{ctx.pkg_ver}.tar.gz', - '{ctx.pkg_repo}-{ctx.pkg_ver}.tar.gz') - unpack( - ctx, - '{ctx.pkg_repo}-{ctx.pkg_ver}.tar.gz', - '{ctx.pkg_repo}-{ctx.pkg_ver}') - changedir(ctx, 'src/{ctx.pkg_repo}-{ctx.pkg_ver}') - execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( - host=ctx.toolchain, - vars=format_vars(ctx), - flags=format_flags(ctx, cflags='-fPIC'), - opts=' '.join([ - '--disable-examples', - '--disable-shared', - '--enable-static', - ]))) - execute_make(ctx) - install_tree(ctx, 'include', ctx.pkg_inc_dir) - install_files(ctx, 'lib{ctx.pkg_repo}/.libs/libspeexdsp.a', ctx.pkg_lib_dir) - elif ctx.pkg_name == 'sndfile': - download( - ctx, - 'http://www.mega-nerd.com/libsndfile/files/libsndfile-{ctx.pkg_ver}.tar.gz', - 'libsndfile-{ctx.pkg_ver}.tar.gz') - unpack( - ctx, - 'libsndfile-{ctx.pkg_ver}.tar.gz', - 'libsndfile-{ctx.pkg_ver}') - changedir(ctx, 'src/libsndfile-{ctx.pkg_ver}') - execute(ctx, '{configure} --host={host} {vars} {flags} {opts}'.format( - configure=' '.join(filter(None, [ - # workaround for outdated config.sub - 'ac_cv_host=%s' % ctx.toolchain if ctx.toolchain else '', - # configure - './configure', - ])), - host=ctx.toolchain, - vars=format_vars(ctx), - # explicitly enable -pthread because libtool doesn't add it on some platforms - flags=format_flags(ctx, cflags='-fPIC', pthread=True), - opts=' '.join([ - '--disable-external-libs', - '--disable-shared', - '--enable-static', - ]))) - execute_make(ctx) - install_files(ctx, 'src/sndfile.h', ctx.pkg_inc_dir) - install_files(ctx, 'src/.libs/libsndfile.a', ctx.pkg_lib_dir) - elif ctx.pkg_name == 'sox': - download( - ctx, - 'https://downloads.sourceforge.net/project/sox/sox/' - '{ctx.pkg_ver}/sox-{ctx.pkg_ver}.tar.gz', - 'sox-{ctx.pkg_ver}.tar.gz') - unpack( - ctx, - 'sox-{ctx.pkg_ver}.tar.gz', - 'sox-{ctx.pkg_ver}') - changedir(ctx, 'src/sox-{ctx.pkg_ver}') + shutil.copy('libuv.a', '../libuv.a') + changedir(ctx, '..') + else: + subst_files(ctx, 'src/unix/core.c', ' dup3', ' uv__dup3') + execute(ctx, './autogen.sh') execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( host=ctx.toolchain, vars=format_vars(ctx), - flags=format_flags(ctx, cflags='-w -Wno-incompatible-function-pointer-types'), + flags=format_flags(ctx), opts=' '.join([ - '--disable-openmp', - '--disable-shared', + '--with-pic', '--enable-static', - '--with-amrnb=no', - '--with-amrwb=no', - '--with-ao=no', - '--with-flac=no', - '--with-gsm=no', - '--with-lpc10=no', - '--with-mp3=no', - '--with-oggvorbis=no', - '--with-opus=no', - '--with-pulseaudio=no', - '--with-sndfile=no', - '--with-sndio=no', - '--with-wavpack=no', - '--without-ao', - '--without-id3tag', - '--without-ladspa', - '--without-lame', - '--without-libltdl', - '--without-mad', - '--without-magic', - '--without-opus', - '--without-png', - '--without-twolame', ]))) execute_make(ctx) - install_files(ctx, 'src/sox.h', ctx.pkg_inc_dir) - install_files(ctx, 'src/.libs/libsox.a', ctx.pkg_lib_dir) - elif ctx.pkg_name == 'alsa': - download( - ctx, - 'https://www.alsa-project.org/files/pub/lib/alsa-lib-{ctx.pkg_ver}.tar.bz2', - 'alsa-lib-{ctx.pkg_ver}.tar.bz2') - unpack(ctx, - 'alsa-lib-{ctx.pkg_ver}.tar.bz2', - 'alsa-lib-{ctx.pkg_ver}') - changedir(ctx, 'src/alsa-lib-{ctx.pkg_ver}') - execute(ctx, './configure --host={host} {vars} {opts}'.format( - host=ctx.toolchain, - vars=format_vars(ctx), - opts=' '.join([ - '--disable-python', - '--disable-static', - '--enable-shared', - ]))) - execute_make(ctx) - install_tree(ctx, 'include/alsa', - os.path.join(ctx.pkg_inc_dir, 'alsa'), - exclude=['alsa']) - install_files(ctx, 'src/.libs/libasound.so', ctx.pkg_lib_dir) - install_files(ctx, 'src/.libs/libasound.so.*', ctx.pkg_rpath_dir) - elif ctx.pkg_name == 'pulseaudio': - download( - ctx, - 'https://freedesktop.org/software/pulseaudio/releases/' - 'pulseaudio-{ctx.pkg_ver}.tar.gz', - 'pulseaudio-{ctx.pkg_ver}.tar.gz') - unpack( - ctx, + shutil.copy('.libs/libuv.a', 'libuv.a') + install_tree(ctx, 'include', ctx.pkg_inc_dir) + install_files(ctx, 'libuv.a', ctx.pkg_lib_dir) +elif ctx.pkg_name == 'libatomic_ops': + download( + ctx, + 'https://github.com/ivmai/libatomic_ops/releases/download/' + 'v{ctx.pkg_ver}/libatomic_ops-{ctx.pkg_ver}.tar.gz', + 'libatomic_ops-{ctx.pkg_ver}.tar.gz') + unpack(ctx, + 'libatomic_ops-{ctx.pkg_ver}.tar.gz', + 'libatomic_ops-{ctx.pkg_ver}') + changedir(ctx, 'src/libatomic_ops-{ctx.pkg_ver}') + execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( + host=ctx.toolchain, + vars=format_vars(ctx), + flags=format_flags(ctx, cflags='-fPIC'), + opts=' '.join([ + '--disable-docs', + '--disable-shared', + '--enable-static', + ]))) + execute_make(ctx) + install_tree(ctx, 'src', ctx.pkg_inc_dir, include=['*.h']) + install_files(ctx, 'src/.libs/libatomic_ops.a', ctx.pkg_lib_dir) +elif ctx.pkg_name == 'libunwind': + download( + ctx, + 'http://download.savannah.nongnu.org/releases/libunwind/' + 'libunwind-{ctx.pkg_ver}.tar.gz', + 'libunwind-{ctx.pkg_ver}.tar.gz') + unpack(ctx, + 'libunwind-{ctx.pkg_ver}.tar.gz', + 'libunwind-{ctx.pkg_ver}') + changedir(ctx, 'src/libunwind-{ctx.pkg_ver}') + execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( + host=ctx.toolchain, + vars=format_vars(ctx), + flags=format_flags(ctx, cflags='-fcommon -fPIC'), + opts=' '.join([ + '--disable-coredump', + '--disable-minidebuginfo', + '--disable-ptrace', + '--disable-setjmp', + '--disable-shared', + '--enable-static', + ]))) + execute_make(ctx) + install_files(ctx, 'include/*.h', ctx.pkg_inc_dir) + install_files(ctx, 'src/.libs/libunwind.a', ctx.pkg_lib_dir) +elif ctx.pkg_name == 'libuuid': + download( + ctx, + 'https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/'+ + 'v{ctx.pkg_ver_major}.{ctx.pkg_ver_minor}/util-linux-{ctx.pkg_ver}.tar.gz', + 'util-linux-{ctx.pkg_ver}.tar.gz') + unpack(ctx, + 'util-linux-{ctx.pkg_ver}.tar.gz', + 'util-linux-{ctx.pkg_ver}') + changedir(ctx, 'src/util-linux-{ctx.pkg_ver}') + execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( + host=ctx.toolchain, + vars=format_vars(ctx), + flags=format_flags(ctx, cflags='-fcommon -fPIC'), + opts=' '.join([ + '--disable-year2038', + '--disable-all-programs', + '--enable-libuuid', + ]))) + execute_make(ctx) + install_files(ctx, 'libuuid/src/uuid.h', ctx.pkg_inc_dir) + install_files(ctx, '.libs/libuuid.a', ctx.pkg_lib_dir) +elif ctx.pkg_name == 'openfec': + if ctx.variant == 'debug': + setattr(ctx, 'res_dir', 'bin/Debug') + else: + setattr(ctx, 'res_dir', 'bin/Release') + download( + ctx, + 'https://github.com/roc-streaming/openfec/archive/v{ctx.pkg_ver}.tar.gz', + 'openfec_v{ctx.pkg_ver}.tar.gz') + unpack(ctx, + 'openfec_v{ctx.pkg_ver}.tar.gz', + 'openfec-{ctx.pkg_ver}') + changedir(ctx, 'src/openfec-{ctx.pkg_ver}') + mkpath('build') + changedir(ctx, 'build') + execute_cmake(ctx, '..', args=[ + '-DBUILD_STATIC_LIBS=ON', + '-DDEBUG:STRING=%s' % ('ON' if ctx.variant == 'debug' else 'OFF'), + ]) + execute_cmake_build(ctx) + changedir(ctx, '..') + install_tree(ctx, 'src', ctx.pkg_inc_dir, include=['*.h']) + install_files(ctx, '{ctx.res_dir}/libopenfec.a', ctx.pkg_lib_dir) +elif ctx.pkg_name == 'openssl': + download( + ctx, + 'https://www.openssl.org/source/openssl-{ctx.pkg_ver}.tar.gz', + 'openssl-{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + 'openssl-{ctx.pkg_ver}.tar.gz', + 'openssl-{ctx.pkg_ver}') + changedir(ctx, 'src/openssl-{ctx.pkg_ver}') + # see https://github.com/openssl/openssl/blob/master/INSTALL.md#configuration-options + execute(ctx, '{vars} {flags} ./Configure {platform} {variant} {options}'.format( + vars=format_vars(ctx, disable_launcher=True), + flags=format_flags(ctx), + platform=detect_openssl_platform(ctx.host), + variant='--debug' if ctx.variant == 'debug' else '--release', + options=' '.join([ + 'no-asan', + 'no-buildtest-c++', + 'no-external-tests', + 'no-fuzz-afl', + 'no-fuzz-libfuzzer', + 'no-shared', + 'no-tests', + 'no-ubsan', + 'no-ui-console', + 'no-unit-test', + ]))) + execute_make(ctx) + install_tree(ctx, 'include', ctx.pkg_inc_dir) + install_files(ctx, 'libssl.a', ctx.pkg_lib_dir) + install_files(ctx, 'libcrypto.a', ctx.pkg_lib_dir) +elif ctx.pkg_name == 'speexdsp': + if ctx.pkg_ver.split('.', 1) > ['1', '2'] and ( + not re.match('^1.2[a-z]', ctx.pkg_ver) or ctx.pkg_ver == '1.2rc3'): + setattr(ctx, 'pkg_repo', 'speexdsp') + else: + setattr(ctx, 'pkg_repo', 'speex') + download( + ctx, + 'http://downloads.xiph.org/releases/speex/{ctx.pkg_repo}-{ctx.pkg_ver}.tar.gz', + '{ctx.pkg_repo}-{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + '{ctx.pkg_repo}-{ctx.pkg_ver}.tar.gz', + '{ctx.pkg_repo}-{ctx.pkg_ver}') + changedir(ctx, 'src/{ctx.pkg_repo}-{ctx.pkg_ver}') + execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( + host=ctx.toolchain, + vars=format_vars(ctx), + flags=format_flags(ctx, cflags='-fPIC'), + opts=' '.join([ + '--disable-examples', + '--disable-shared', + '--enable-static', + ]))) + execute_make(ctx) + install_tree(ctx, 'include', ctx.pkg_inc_dir) + install_files(ctx, 'lib{ctx.pkg_repo}/.libs/libspeexdsp.a', ctx.pkg_lib_dir) +elif ctx.pkg_name == 'sndfile': + download( + ctx, + 'http://www.mega-nerd.com/libsndfile/files/libsndfile-{ctx.pkg_ver}.tar.gz', + 'libsndfile-{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + 'libsndfile-{ctx.pkg_ver}.tar.gz', + 'libsndfile-{ctx.pkg_ver}') + changedir(ctx, 'src/libsndfile-{ctx.pkg_ver}') + execute(ctx, '{configure} --host={host} {vars} {flags} {opts}'.format( + configure=' '.join(filter(None, [ + # workaround for outdated config.sub + 'ac_cv_host=%s' % ctx.toolchain if ctx.toolchain else '', + # configure + './configure', + ])), + host=ctx.toolchain, + vars=format_vars(ctx), + # explicitly enable -pthread because libtool doesn't add it on some platforms + flags=format_flags(ctx, cflags='-fPIC', pthread=True), + opts=' '.join([ + '--disable-external-libs', + '--disable-shared', + '--enable-static', + ]))) + execute_make(ctx) + install_files(ctx, 'src/sndfile.h', ctx.pkg_inc_dir) + install_files(ctx, 'src/.libs/libsndfile.a', ctx.pkg_lib_dir) +elif ctx.pkg_name == 'sox': + download( + ctx, + 'https://downloads.sourceforge.net/project/sox/sox/' + '{ctx.pkg_ver}/sox-{ctx.pkg_ver}.tar.gz', + 'sox-{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + 'sox-{ctx.pkg_ver}.tar.gz', + 'sox-{ctx.pkg_ver}') + changedir(ctx, 'src/sox-{ctx.pkg_ver}') + execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( + host=ctx.toolchain, + vars=format_vars(ctx), + flags=format_flags(ctx, cflags='-w -Wno-incompatible-function-pointer-types'), + opts=' '.join([ + '--disable-openmp', + '--disable-shared', + '--enable-static', + '--with-amrnb=no', + '--with-amrwb=no', + '--with-ao=no', + '--with-flac=no', + '--with-gsm=no', + '--with-lpc10=no', + '--with-mp3=no', + '--with-oggvorbis=no', + '--with-opus=no', + '--with-pulseaudio=no', + '--with-sndfile=no', + '--with-sndio=no', + '--with-wavpack=no', + '--without-ao', + '--without-id3tag', + '--without-ladspa', + '--without-lame', + '--without-libltdl', + '--without-mad', + '--without-magic', + '--without-opus', + '--without-png', + '--without-twolame', + ]))) + execute_make(ctx) + install_files(ctx, 'src/sox.h', ctx.pkg_inc_dir) + install_files(ctx, 'src/.libs/libsox.a', ctx.pkg_lib_dir) +elif ctx.pkg_name == 'alsa': + download( + ctx, + 'https://www.alsa-project.org/files/pub/lib/alsa-lib-{ctx.pkg_ver}.tar.bz2', + 'alsa-lib-{ctx.pkg_ver}.tar.bz2') + unpack(ctx, + 'alsa-lib-{ctx.pkg_ver}.tar.bz2', + 'alsa-lib-{ctx.pkg_ver}') + changedir(ctx, 'src/alsa-lib-{ctx.pkg_ver}') + execute(ctx, './configure --host={host} {vars} {opts}'.format( + host=ctx.toolchain, + vars=format_vars(ctx), + opts=' '.join([ + '--disable-python', + '--disable-static', + '--enable-shared', + ]))) + execute_make(ctx) + install_tree(ctx, 'include/alsa', + os.path.join(ctx.pkg_inc_dir, 'alsa'), + exclude=['alsa']) + install_files(ctx, 'src/.libs/libasound.so', ctx.pkg_lib_dir) + install_files(ctx, 'src/.libs/libasound.so.*', ctx.pkg_rpath_dir) +elif ctx.pkg_name == 'pulseaudio': + download( + ctx, + 'https://freedesktop.org/software/pulseaudio/releases/' 'pulseaudio-{ctx.pkg_ver}.tar.gz', - 'pulseaudio-{ctx.pkg_ver}') - pa_ver = parse_ver(ctx.pkg_ver, int) - if (8, 99, 1) <= pa_ver < (11, 99, 1): - apply_patch( - ctx, - 'src/pulseaudio-{ctx.pkg_ver}', - 'https://bugs.freedesktop.org/attachment.cgi?id=136927', - '0001-memfd-wrappers-only-define-memfd_create-if-not-alrea.patch') - if pa_ver < (12, 99, 1): - subst_tree(ctx, 'src/pulseaudio-{ctx.pkg_ver}', ['*.h', '*.c'], - from_='#include ', - to='#include ') - changedir(ctx, 'src/pulseaudio-{ctx.pkg_ver}') - if pa_ver < (14, 99, 1): - # workaround for "missing acolocal-1.15" and "missing automake-1.15" errors - # on some systems; since we're not modifying any autotools stuff, it's safe - # to replace corresponding commands with "true" command - if os.path.exists('Makefile.in'): - subst_files(ctx, 'Makefile.in', '@ACLOCAL@', 'true') - subst_files(ctx, 'Makefile.in', '@AUTOMAKE@', 'true') - execute(ctx, './configure --host={host} {vars} {flags} {deps} {opts}'.format( - host=ctx.toolchain, - vars=format_vars(ctx), - flags=format_flags(ctx, cflags='-w -Wno-implicit-function-declaration' + \ - ' -fomit-frame-pointer -O2'), - deps=' '.join([ - 'LIBJSON_CFLAGS=" "', - 'LIBJSON_LIBS="-ljson-c"', - 'LIBSNDFILE_CFLAGS=" "', - 'LIBSNDFILE_LIBS="-lsndfile"', - ]), - opts=' '.join([ - '--disable-manpages', - '--disable-neon-opt', - '--disable-openssl', - '--disable-orc', - '--disable-static', - '--disable-tests', - '--disable-webrtc-aec', - '--enable-shared', - '--without-caps', - ]))) - execute_make(ctx) - install_files(ctx, 'config.h', ctx.pkg_inc_dir) - install_tree(ctx, 'src/pulse', os.path.join(ctx.pkg_inc_dir, 'pulse'), - include=['*.h']) - install_files(ctx, 'src/.libs/libpulse.so', ctx.pkg_lib_dir) - install_files(ctx, 'src/.libs/libpulse.so.0', ctx.pkg_rpath_dir) - install_files(ctx, 'src/.libs/libpulse-simple.so', ctx.pkg_lib_dir) - install_files(ctx, 'src/.libs/libpulse-simple.so.0', ctx.pkg_rpath_dir) - install_files(ctx, 'src/.libs/libpulsecommon-*.so', ctx.pkg_lib_dir) - install_files(ctx, 'src/.libs/libpulsecommon-*.so', ctx.pkg_rpath_dir) - else: - mkpath('builddir') - changedir(ctx, 'builddir') - mkpath('pcdir') - generate_pc_files(ctx, 'pcdir') - generate_meson_crossfile(ctx, 'pcdir', 'crossfile.txt') - execute(ctx, 'meson .. {opts}'.format( - opts=' '.join([ - '--cross-file=crossfile.txt', - '-Ddaemon=false', - '-Ddoxygen=false', - '-Dgcov=false', - '-Dman=false', - '-Dtests=false', - ]))) - execute(ctx, 'ninja') - execute(ctx, 'DESTDIR=../instdir ninja install') - changedir(ctx, '..') - install_tree(ctx, 'instdir/usr/local/include/pulse', - os.path.join(ctx.pkg_inc_dir, 'pulse'), - include=['*.h']) - install_files(ctx, 'builddir/src/pulse/libpulse.so', ctx.pkg_lib_dir) - install_files(ctx, 'builddir/src/pulse/libpulse.so.0', ctx.pkg_rpath_dir) - install_files(ctx, 'builddir/src/pulse/libpulse-simple.so', ctx.pkg_lib_dir) - install_files(ctx, 'builddir/src/pulse/libpulse-simple.so.0', ctx.pkg_rpath_dir) - install_files(ctx, 'builddir/src/libpulsecommon-*.so', ctx.pkg_lib_dir) - install_files(ctx, 'builddir/src/libpulsecommon-*.so', ctx.pkg_rpath_dir) - elif ctx.pkg_name == 'ltdl': - download( - ctx, - 'https://ftp.gnu.org/gnu/libtool/libtool-{ctx.pkg_ver}.tar.gz', - 'libtool-{ctx.pkg_ver}.tar.gz') - unpack( + 'pulseaudio-{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + 'pulseaudio-{ctx.pkg_ver}.tar.gz', + 'pulseaudio-{ctx.pkg_ver}') + pa_ver = parse_ver(ctx.pkg_ver, int) + if (8, 99, 1) <= pa_ver < (11, 99, 1): + apply_patch( ctx, - 'libtool-{ctx.pkg_ver}.tar.gz', - 'libtool-{ctx.pkg_ver}') - changedir(ctx, 'src/libtool-{ctx.pkg_ver}') - execute(ctx, './configure --host={host} {vars} {opts}'.format( + 'src/pulseaudio-{ctx.pkg_ver}', + 'https://bugs.freedesktop.org/attachment.cgi?id=136927', + '0001-memfd-wrappers-only-define-memfd_create-if-not-alrea.patch') + if pa_ver < (12, 99, 1): + subst_tree(ctx, 'src/pulseaudio-{ctx.pkg_ver}', ['*.h', '*.c'], + from_='#include ', + to='#include ') + changedir(ctx, 'src/pulseaudio-{ctx.pkg_ver}') + if pa_ver < (14, 99, 1): + # workaround for "missing acolocal-1.15" and "missing automake-1.15" errors + # on some systems; since we're not modifying any autotools stuff, it's safe + # to replace corresponding commands with "true" command + if os.path.exists('Makefile.in'): + subst_files(ctx, 'Makefile.in', '@ACLOCAL@', 'true') + subst_files(ctx, 'Makefile.in', '@AUTOMAKE@', 'true') + execute(ctx, './configure --host={host} {vars} {flags} {deps} {opts}'.format( host=ctx.toolchain, vars=format_vars(ctx), + flags=format_flags(ctx, cflags='-w -Wno-implicit-function-declaration' + \ + ' -fomit-frame-pointer -O2'), + deps=' '.join([ + 'LIBJSON_CFLAGS=" "', + 'LIBJSON_LIBS="-ljson-c"', + 'LIBSNDFILE_CFLAGS=" "', + 'LIBSNDFILE_LIBS="-lsndfile"', + ]), opts=' '.join([ + '--disable-manpages', + '--disable-neon-opt', + '--disable-openssl', + '--disable-orc', '--disable-static', + '--disable-tests', + '--disable-webrtc-aec', '--enable-shared', + '--without-caps', ]))) execute_make(ctx) - install_files(ctx, 'libltdl/ltdl.h', ctx.pkg_inc_dir) - install_tree(ctx, 'libltdl/libltdl', os.path.join(ctx.pkg_inc_dir, 'libltdl')) - install_files(ctx, 'libltdl/.libs/libltdl.so', ctx.pkg_lib_dir) - install_files(ctx, 'libltdl/.libs/libltdl.so.*', ctx.pkg_rpath_dir) - elif ctx.pkg_name == 'json-c': - download( - ctx, - 'https://github.com/json-c/json-c/archive/json-c-{ctx.pkg_ver}.tar.gz', - 'json-c-{ctx.pkg_ver}.tar.gz') - unpack( - ctx, - 'json-c-{ctx.pkg_ver}.tar.gz', - 'json-c-json-c-{ctx.pkg_ver}') - changedir(ctx, 'src/json-c-json-c-{ctx.pkg_ver}') - execute(ctx, '{configure} --host={host} {vars} {flags} {opts}'.format( - configure=' '.join(filter(None, [ - # workaround for outdated config.sub - 'ac_cv_host=%s' % ctx.toolchain if ctx.toolchain else '', - # disable rpl_malloc and rpl_realloc - 'ac_cv_func_malloc_0_nonnull=yes', - 'ac_cv_func_realloc_0_nonnull=yes', - # configure - './configure', - ])), - host=ctx.toolchain, - vars=format_vars(ctx), - flags=format_flags(ctx, cflags='-w -fPIC'), + install_files(ctx, 'config.h', ctx.pkg_inc_dir) + install_tree(ctx, 'src/pulse', os.path.join(ctx.pkg_inc_dir, 'pulse'), + include=['*.h']) + install_files(ctx, 'src/.libs/libpulse.so', ctx.pkg_lib_dir) + install_files(ctx, 'src/.libs/libpulse.so.0', ctx.pkg_rpath_dir) + install_files(ctx, 'src/.libs/libpulse-simple.so', ctx.pkg_lib_dir) + install_files(ctx, 'src/.libs/libpulse-simple.so.0', ctx.pkg_rpath_dir) + install_files(ctx, 'src/.libs/libpulsecommon-*.so', ctx.pkg_lib_dir) + install_files(ctx, 'src/.libs/libpulsecommon-*.so', ctx.pkg_rpath_dir) + else: + mkpath('builddir') + changedir(ctx, 'builddir') + mkpath('pcdir') + generate_pc_files(ctx, 'pcdir') + generate_meson_crossfile(ctx, 'pcdir', 'crossfile.txt') + execute(ctx, 'meson .. {opts}'.format( opts=' '.join([ - '--enable-static', - '--disable-shared', + '--cross-file=crossfile.txt', + '-Ddaemon=false', + '-Ddoxygen=false', + '-Dgcov=false', + '-Dman=false', + '-Dtests=false', ]))) - execute_make(ctx, cpu_count=0) # -j is buggy for json-c - install_tree(ctx, '.', ctx.pkg_inc_dir, include=['*.h']) - install_files(ctx, '.libs/libjson-c.a', ctx.pkg_lib_dir) - elif ctx.pkg_name == 'gengetopt': - native_compilers = detect_native_cc_cxx_compilers(); - download( - ctx, - 'https://ftp.gnu.org/gnu/gengetopt/gengetopt-{ctx.pkg_ver}.tar.gz', - 'gengetopt-{ctx.pkg_ver}.tar.gz') - unpack( - ctx, - 'gengetopt-{ctx.pkg_ver}.tar.gz', - 'gengetopt-{ctx.pkg_ver}') - changedir(ctx, 'src/gengetopt-{ctx.pkg_ver}') - execute(ctx, './configure {vars}'.format( - vars=format_vars(ctx, False, env={ - 'CC' : native_compilers.get('CC', None), - 'CXX' : native_compilers.get('CXX', None), - 'COMPILER_LAUNCHER' : ctx.env.get('COMPILER_LAUNCHER', None), - }), - clear_env=True)) - execute_make(ctx, cpu_count=0) # -j is buggy for gengetopt - install_files(ctx, 'src/gengetopt', ctx.pkg_bin_dir) - elif ctx.pkg_name == 'ragel': - native_compilers = detect_native_cc_cxx_compilers(); - download( - ctx, - 'https://www.colm.net/files/ragel/ragel-{ctx.pkg_ver}.tar.gz', - 'ragel-{ctx.pkg_ver}.tar.gz') - unpack( - ctx, - 'ragel-{ctx.pkg_ver}.tar.gz', - 'ragel-{ctx.pkg_ver}') - changedir(ctx, 'src/ragel-{ctx.pkg_ver}') - execute(ctx, './configure {vars}'.format( - vars=format_vars(ctx, False, env={ - 'CC' : native_compilers.get('CC', None), - 'CXX' : native_compilers.get('CXX', None), - 'COMPILER_LAUNCHER' : ctx.env.get('COMPILER_LAUNCHER', None), - }), - clear_env=True)) - execute_make(ctx) - install_files(ctx, 'ragel/ragel', ctx.pkg_bin_dir) - elif ctx.pkg_name == 'cpputest': - download( - ctx, - 'https://github.com/cpputest/cpputest/releases/download/' - 'v{ctx.pkg_ver}/cpputest-{ctx.pkg_ver}.tar.gz', - 'cpputest-{ctx.pkg_ver}.tar.gz') - unpack( - ctx, - 'cpputest-{ctx.pkg_ver}.tar.gz', - 'cpputest-{ctx.pkg_ver}') - changedir(ctx, 'src/cpputest-{ctx.pkg_ver}') - if ctx.prefer_cmake: - mkpath('build') - changedir(ctx, 'build') - execute_cmake(ctx, '..', args=[ - '-DMEMORY_LEAK_DETECTION=OFF', - '-DTESTS=OFF', - '-DBUILD_SHARED_LIBS=OFF', - ]) - execute_cmake_build(ctx) - shutil.copy('src/CppUTest/libCppUTest.a', '../libCppUTest.a') - changedir(ctx, '..') - else: - execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( - host=ctx.toolchain, - vars=format_vars(ctx), - # disable warnings, since CppUTest uses -Werror and may fail to - # build on old GCC versions - flags=format_flags(ctx, cflags='-w'), - opts=' '.join([ - # disable memory leak detection which is too hard to use properly - '--disable-memory-leak-detection', - # doesn't work on older platforms - '--disable-extensions', - '--enable-static', - ]))) - execute_make(ctx) - shutil.copy('lib/libCppUTest.a', 'libCppUTest.a') - install_tree(ctx, 'include', ctx.pkg_inc_dir) - install_files(ctx, 'libCppUTest.a', ctx.pkg_lib_dir) - elif ctx.pkg_name == 'google-benchmark': - download( - ctx, - 'https://github.com/google/benchmark/archive/v{ctx.pkg_ver}.tar.gz', - 'benchmark_v{ctx.pkg_ver}.tar.gz') - unpack( - ctx, - 'benchmark_v{ctx.pkg_ver}.tar.gz', - 'benchmark-{ctx.pkg_ver}') - changedir(ctx, 'src/benchmark-{ctx.pkg_ver}') - bench_ver = parse_ver(ctx.pkg_ver, int) - if bench_ver < (1, 7, 1) and not which('python') and which('python3'): - subst_tree( - ctx, 'tools', ['*.py'], - from_='#!/usr/bin/env python', to='#!/usr/bin/env python3') + execute(ctx, 'ninja') + execute(ctx, 'DESTDIR=../instdir ninja install') + changedir(ctx, '..') + install_tree(ctx, 'instdir/usr/local/include/pulse', + os.path.join(ctx.pkg_inc_dir, 'pulse'), + include=['*.h']) + install_files(ctx, 'builddir/src/pulse/libpulse.so', ctx.pkg_lib_dir) + install_files(ctx, 'builddir/src/pulse/libpulse.so.0', ctx.pkg_rpath_dir) + install_files(ctx, 'builddir/src/pulse/libpulse-simple.so', ctx.pkg_lib_dir) + install_files(ctx, 'builddir/src/pulse/libpulse-simple.so.0', ctx.pkg_rpath_dir) + install_files(ctx, 'builddir/src/libpulsecommon-*.so', ctx.pkg_lib_dir) + install_files(ctx, 'builddir/src/libpulsecommon-*.so', ctx.pkg_rpath_dir) +elif ctx.pkg_name == 'ltdl': + download( + ctx, + 'https://ftp.gnu.org/gnu/libtool/libtool-{ctx.pkg_ver}.tar.gz', + 'libtool-{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + 'libtool-{ctx.pkg_ver}.tar.gz', + 'libtool-{ctx.pkg_ver}') + changedir(ctx, 'src/libtool-{ctx.pkg_ver}') + execute(ctx, './configure --host={host} {vars} {opts}'.format( + host=ctx.toolchain, + vars=format_vars(ctx), + opts=' '.join([ + '--disable-static', + '--enable-shared', + ]))) + execute_make(ctx) + install_files(ctx, 'libltdl/ltdl.h', ctx.pkg_inc_dir) + install_tree(ctx, 'libltdl/libltdl', os.path.join(ctx.pkg_inc_dir, 'libltdl')) + install_files(ctx, 'libltdl/.libs/libltdl.so', ctx.pkg_lib_dir) + install_files(ctx, 'libltdl/.libs/libltdl.so.*', ctx.pkg_rpath_dir) +elif ctx.pkg_name == 'json-c': + download( + ctx, + 'https://github.com/json-c/json-c/archive/json-c-{ctx.pkg_ver}.tar.gz', + 'json-c-{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + 'json-c-{ctx.pkg_ver}.tar.gz', + 'json-c-json-c-{ctx.pkg_ver}') + changedir(ctx, 'src/json-c-json-c-{ctx.pkg_ver}') + execute(ctx, '{configure} --host={host} {vars} {flags} {opts}'.format( + configure=' '.join(filter(None, [ + # workaround for outdated config.sub + 'ac_cv_host=%s' % ctx.toolchain if ctx.toolchain else '', + # disable rpl_malloc and rpl_realloc + 'ac_cv_func_malloc_0_nonnull=yes', + 'ac_cv_func_realloc_0_nonnull=yes', + # configure + './configure', + ])), + host=ctx.toolchain, + vars=format_vars(ctx), + flags=format_flags(ctx, cflags='-w -fPIC'), + opts=' '.join([ + '--enable-static', + '--disable-shared', + ]))) + execute_make(ctx, cpu_count=0) # -j is buggy for json-c + install_tree(ctx, '.', ctx.pkg_inc_dir, include=['*.h']) + install_files(ctx, '.libs/libjson-c.a', ctx.pkg_lib_dir) +elif ctx.pkg_name == 'gengetopt': + native_compilers = detect_native_cc_cxx_compilers(); + download( + ctx, + 'https://ftp.gnu.org/gnu/gengetopt/gengetopt-{ctx.pkg_ver}.tar.gz', + 'gengetopt-{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + 'gengetopt-{ctx.pkg_ver}.tar.gz', + 'gengetopt-{ctx.pkg_ver}') + changedir(ctx, 'src/gengetopt-{ctx.pkg_ver}') + execute(ctx, './configure {vars}'.format( + vars=format_vars(ctx, False, env={ + 'CC' : native_compilers.get('CC', None), + 'CXX' : native_compilers.get('CXX', None), + 'COMPILER_LAUNCHER' : ctx.env.get('COMPILER_LAUNCHER', None), + }), + clear_env=True)) + execute_make(ctx, cpu_count=0) # -j is buggy for gengetopt + install_files(ctx, 'src/gengetopt', ctx.pkg_bin_dir) +elif ctx.pkg_name == 'ragel': + native_compilers = detect_native_cc_cxx_compilers(); + download( + ctx, + 'https://www.colm.net/files/ragel/ragel-{ctx.pkg_ver}.tar.gz', + 'ragel-{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + 'ragel-{ctx.pkg_ver}.tar.gz', + 'ragel-{ctx.pkg_ver}') + changedir(ctx, 'src/ragel-{ctx.pkg_ver}') + execute(ctx, './configure {vars}'.format( + vars=format_vars(ctx, False, env={ + 'CC' : native_compilers.get('CC', None), + 'CXX' : native_compilers.get('CXX', None), + 'COMPILER_LAUNCHER' : ctx.env.get('COMPILER_LAUNCHER', None), + }), + clear_env=True)) + execute_make(ctx) + install_files(ctx, 'ragel/ragel', ctx.pkg_bin_dir) +elif ctx.pkg_name == 'cpputest': + download( + ctx, + 'https://github.com/cpputest/cpputest/releases/download/' + 'v{ctx.pkg_ver}/cpputest-{ctx.pkg_ver}.tar.gz', + 'cpputest-{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + 'cpputest-{ctx.pkg_ver}.tar.gz', + 'cpputest-{ctx.pkg_ver}') + changedir(ctx, 'src/cpputest-{ctx.pkg_ver}') + if ctx.prefer_cmake: mkpath('build') changedir(ctx, 'build') execute_cmake(ctx, '..', args=[ - '-DBENCHMARK_ENABLE_GTEST_TESTS=OFF', - '-DCMAKE_CXX_FLAGS=-w', + '-DMEMORY_LEAK_DETECTION=OFF', + '-DTESTS=OFF', + '-DBUILD_SHARED_LIBS=OFF', ]) execute_cmake_build(ctx) + shutil.copy('src/CppUTest/libCppUTest.a', '../libCppUTest.a') changedir(ctx, '..') - install_tree(ctx, 'include', ctx.pkg_inc_dir, include=['*.h']) - install_files(ctx, 'build/src/libbenchmark.a', ctx.pkg_lib_dir) - # end of deps else: - die("unknown 3rdparty '{}'", ctx.pkg) - - # commit successful build - touch(ctx.commit_file) + execute(ctx, './configure --host={host} {vars} {flags} {opts}'.format( + host=ctx.toolchain, + vars=format_vars(ctx), + # disable warnings, since CppUTest uses -Werror and may fail to + # build on old GCC versions + flags=format_flags(ctx, cflags='-w'), + opts=' '.join([ + # disable memory leak detection which is too hard to use properly + '--disable-memory-leak-detection', + # doesn't work on older platforms + '--disable-extensions', + '--enable-static', + ]))) + execute_make(ctx) + shutil.copy('lib/libCppUTest.a', 'libCppUTest.a') + install_tree(ctx, 'include', ctx.pkg_inc_dir) + install_files(ctx, 'libCppUTest.a', ctx.pkg_lib_dir) +elif ctx.pkg_name == 'google-benchmark': + download( + ctx, + 'https://github.com/google/benchmark/archive/v{ctx.pkg_ver}.tar.gz', + 'benchmark_v{ctx.pkg_ver}.tar.gz') + unpack( + ctx, + 'benchmark_v{ctx.pkg_ver}.tar.gz', + 'benchmark-{ctx.pkg_ver}') + changedir(ctx, 'src/benchmark-{ctx.pkg_ver}') + bench_ver = parse_ver(ctx.pkg_ver, int) + if bench_ver < (1, 7, 1) and not which('python') and which('python3'): + subst_tree( + ctx, 'tools', ['*.py'], + from_='#!/usr/bin/env python', to='#!/usr/bin/env python3') + mkpath('build') + changedir(ctx, 'build') + execute_cmake(ctx, '..', args=[ + '-DBENCHMARK_ENABLE_GTEST_TESTS=OFF', + '-DCMAKE_CXX_FLAGS=-w', + ]) + execute_cmake_build(ctx) + changedir(ctx, '..') + install_tree(ctx, 'include', ctx.pkg_inc_dir, include=['*.h']) + install_files(ctx, 'build/src/libbenchmark.a', ctx.pkg_lib_dir) +# end of deps +else: + die("unknown 3rdparty '{}'", ctx.pkg) + +# commit successful build +touch(ctx.commit_file) diff --git a/scripts/scons_helpers/doctests.py b/scripts/scons_helpers/doctests.py deleted file mode 100644 index c0f3fe7e5..000000000 --- a/scripts/scons_helpers/doctests.py +++ /dev/null @@ -1,112 +0,0 @@ -import doctest -import importlib.util -import os -import os.path -import sys -import time -import unittest - -class CompactTextTestResult(unittest.TextTestResult): - - def __init__(self, stream, descriptions, verbosity): - super().__init__(stream, descriptions, verbosity) - - if os.name == 'posix' and sys.stdout.isatty(): - self.RED = '\033[0;31m' - self.GREEN = '\033[0;32m' - self.YELLOW = '\033[0;33m' - self.BLUE = '\033[0;34m' - self.RESET = '\033[0m' - else: - self.RED = '' - self.GREEN = '' - self.YELLOW = '' - self.BLUE = '' - self.RESET = '' - - def getDescription(self, test): - return test.shortDescription().replace('Doctest: ', '') - - def addSuccess(self, test): - self.stream.write(self.GREEN) - super().addSuccess(test) - self.stream.write(self.RESET) - - def addError(self, test, err): - self.stream.write(self.RED) - super().addError(test, err) - self.stream.write(self.RESET) - - def addFailure(self, test, err): - self.stream.write(self.YELLOW) - super().addFailure(test, err) - self.stream.write(self.RESET) - - def printErrors(self): - self.printErrorList(f"{self.RED}ERROR{self.RESET}", self.errors) - self.printErrorList(f"{self.RED}FAIL{self.RESET}", self.failures) - -class CompactTextTestRunner(unittest.TextTestRunner): - resultclass = CompactTextTestResult - - def __init__(self): - super().__init__(verbosity=2) - - def run(self, test): - result = CompactTextTestResult(self.stream, self.descriptions, self.verbosity) - result.failfast = self.failfast - result.buffer = self.buffer - result.tb_locals = self.tb_locals - start_time = time.perf_counter() - result.startTestRun() - try: - test(result) - finally: - result.stopTestRun() - stop_time = time.perf_counter() - time_taken = (stop_time - start_time) * 1000 - result.printErrors() - - total = result.testsRun - errors = len(result.failures) + len(result.errors) - if errors == 0: - status = 'OK' - else: - status = 'Errors' - - self.stream.writeln("{} ({} failures, {} ran, {} ms)".format( - status, errors, total, int(time_taken))) - self.stream.writeln() - self.stream.flush() - - return result - -cwd = os.path.abspath(os.getcwd()) - -def load_tests(loader, tests, ignore): - test_paths = [] - for arg in sys.argv[1:]: - arg = os.path.join(cwd, arg) - if os.path.isdir(arg): - for root, dirs, files in os.walk(arg): - for name in files: - if name.endswith('.py'): - test_paths.append(os.path.join(root, name)) - else: - test_paths.append(arg) - - for path in test_paths: - package = os.path.basename(os.path.dirname(path)) - name = package + '.' + os.path.splitext(os.path.basename(path))[0] - spec = importlib.util.spec_from_file_location(name, path) - module = importlib.util.module_from_spec(spec) - - sys.modules[name] = module - spec.loader.exec_module(module) - tests.addTests(doctest.DocTestSuite(module)) - - return tests - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromModule(__import__(__name__)) - CompactTextTestRunner().run(suite) diff --git a/scripts/scons_plugin/commands.py b/scripts/scons_plugin/commands.py index aa992c32d..357214b7e 100644 --- a/scripts/scons_plugin/commands.py +++ b/scripts/scons_plugin/commands.py @@ -33,16 +33,11 @@ def HeaderFormat(env, src_dir): src_dir=quote(env.Dir(src_dir).path)), env.PrettyCommand('FMT', env.Dir(src_dir).path, 'yellow')) -def DocTest(env, path): - try: - path = env.Dir(path).path - except: - path = env.File(path).path +def SelfTest(env): return env.Action( - '{python} scripts/scons_helpers/doctests.py {module}'.format( - python=quote(env.GetPythonExecutable()), - module=quote(path)), - env.PrettyCommand('DOCTEST', path, 'green')) + '{python} scripts/scons_helpers/build-3rdparty.py --self-test'.format( + python=quote(env.GetPythonExecutable())), + env.PrettyCommand('TEST', 'build-3rdparty.py', 'green')) def Doxygen(env, build_dir='', html_dir=None, config='', sources=[], werror=False): target = os.path.join(build_dir, 'commit') @@ -302,7 +297,7 @@ def noop(target, source, env): def init(env): env.AddMethod(ClangFormat, 'ClangFormat') env.AddMethod(HeaderFormat, 'HeaderFormat') - env.AddMethod(DocTest, 'DocTest') + env.AddMethod(SelfTest, 'SelfTest') env.AddMethod(Doxygen, 'Doxygen') env.AddMethod(Sphinx, 'Sphinx') env.AddMethod(Ragel, 'Ragel') diff --git a/scripts/scons_plugin/pretty.py b/scripts/scons_plugin/pretty.py index 6b84d5cd6..5e42c0388 100644 --- a/scripts/scons_plugin/pretty.py +++ b/scripts/scons_plugin/pretty.py @@ -1,31 +1,14 @@ -from __future__ import print_function import SCons.Script -import os -import re import sys +import re _COLORS = {} _COMPACT = False -def _have_colors(): - if os.name != 'posix': - return False - if os.environ.get('NO_COLOR', None): - return False - try: - if int(os.environ.get('FORCE_COLOR', '0')) > 0: - return True - except: - pass - if not os.environ.get('TERM', None) or \ - os.environ.get('TERM', '').startswith('dumb'): - return False - return sys.stdout.isatty() - def _init_colors(): global _COLORS - if _have_colors(): + if sys.stdout.isatty(): _COLORS['cyan'] = '\033[0;36m' _COLORS['purple'] = '\033[0;35m' _COLORS['blue'] = '\033[0;34m' @@ -88,13 +71,8 @@ def PrettyCommand(env, command, args, color, cmdline=None): else: return '$CMDLINE' -def ColorPrint(env, color, fmt, *args): - print('{}{}{}'.format(_COLORS[color], fmt.format(*args), _COLORS['end']), - file=sys.stderr) - def init(env): env.AddMethod(PrettyCommand, 'PrettyCommand') - env.AddMethod(ColorPrint, 'ColorPrint') _init_colors() _init_compact() _init_pretty(env) diff --git a/scripts/scons_plugin/sconsutils.py b/scripts/scons_plugin/sconsutils.py index dd5163f7a..04850a7c8 100644 --- a/scripts/scons_plugin/sconsutils.py +++ b/scripts/scons_plugin/sconsutils.py @@ -7,13 +7,9 @@ # Formats message, prints to stderr, and exits with error. def Die(env, fmt, *args): - env.ColorPrint('red', 'error: {}\n', fmt.format(*args).strip()) + print('error: {}\n'.format(fmt.format(*args).strip()), file=sys.stderr) SCons.Script.Exit(1) -# Formats message and prints to stderr. -def Warn(env, fmt, *args): - env.ColorPrint('yellow', 'warning: {}\n', fmt.format(*args).strip()) - # Returns a deep clone of env. # Workaround for buggy behavior of env.Clone() in recent scons. def DeepClone(env): @@ -65,6 +61,5 @@ def MergeFrom(dst_env, src_env, exclude=[]): def init(env): env.AddMethod(Die, 'Die') - env.AddMethod(Warn, 'Warn') env.AddMethod(DeepClone, 'DeepClone') env.AddMethod(MergeFrom, 'MergeFrom') diff --git a/shell.nix b/shell.nix index 97f17bdfb..c89348462 100644 --- a/shell.nix +++ b/shell.nix @@ -1,41 +1,34 @@ { pkgs ? import {} }: -pkgs.clangStdenv.mkDerivation { - name = "clang-shell"; + pkgs.mkShell { + buildInputs = [ + # build deps + pkgs.autoconf + pkgs.automake + pkgs.clang + pkgs.cmake + pkgs.gcc + pkgs.gengetopt + pkgs.gnumake + pkgs.intltool + pkgs.libtool + pkgs.meson + pkgs.pkg-config + pkgs.ragel + pkgs.scons - nativeBuildInputs = [ - pkgs.clang-tools - # A properly wrapped clangd is already made available by the clang-tools derivation. - # clang-tools has to come before clang to set precedence in PATH for clangd. - pkgs.clang + # other deps + pkgs.libpulseaudio + pkgs.libsndfile + pkgs.libunwind + pkgs.libuv + pkgs.openssl + pkgs.sox + pkgs.speexdsp - # build deps - pkgs.autoconf - pkgs.automake - pkgs.cmake - pkgs.gengetopt - pkgs.gnumake - pkgs.intltool - pkgs.libtool - pkgs.meson - pkgs.pkg-config - pkgs.ragel - pkgs.scons - ]; - - buildInputs = [ - # other deps - pkgs.libpulseaudio - pkgs.libsndfile - pkgs.libunwind - pkgs.libuuid - pkgs.libuv - pkgs.openssl - pkgs.sox - pkgs.speexdsp - - # optional deps: formatting, tests, ... - pkgs.cpputest - pkgs.gbenchmark - ]; -} + # optional deps: formatting, tests, ... + pkgs.clang-tools + pkgs.cpputest + pkgs.gbenchmark + ]; + } diff --git a/src/internal_modules/Doxyfile b/src/internal_modules/Doxyfile index b20d298cb..50a5b396c 100644 --- a/src/internal_modules/Doxyfile +++ b/src/internal_modules/Doxyfile @@ -41,16 +41,12 @@ ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = YES -PREDEFINED = \ - ROC_EXPORT= \ - ROC_ALIGNED= \ - ROC_PACKED_BEGIN= \ - ROC_PACKED_END= \ - ROC_PRINTF(x,y)= \ - ROC_NORETURN= \ - ROC_NODISCARD= \ - ROC_NOUNUSED= \ - ROC_NOSANITIZE= +PREDEFINED = \ + ROC_ATTR_NORETURN= \ + ROC_ATTR_NODISCARD= \ + ROC_ATTR_PRINTF(x,y)= \ + ROC_ATTR_PACKED_BEGIN= \ + ROC_ATTR_PACKED_END= OUTPUT_DIRECTORY = ../../build/docs/internal_modules HTML_OUTPUT = ../../../docs/html/doxygen diff --git a/src/internal_modules/roc_address/io_uri.h b/src/internal_modules/roc_address/io_uri.h index ae2ec5b18..c36a360ff 100644 --- a/src/internal_modules/roc_address/io_uri.h +++ b/src/internal_modules/roc_address/io_uri.h @@ -45,7 +45,7 @@ class IoUri : public core::NonCopyable<> { //! Set URI scheme. //! String should not be zero-terminated. - ROC_NODISCARD bool set_scheme(const char* str, size_t str_len); + ROC_ATTR_NODISCARD bool set_scheme(const char* str, size_t str_len); //! URI path. //! May be device name or file path depending on scheme. @@ -54,11 +54,11 @@ class IoUri : public core::NonCopyable<> { //! Set URI path. //! String should be percent-encoded. //! String should not be zero-terminated. - ROC_NODISCARD bool set_encoded_path(const char* str, size_t str_len); + ROC_ATTR_NODISCARD bool set_encoded_path(const char* str, size_t str_len); //! Get URI path. //! String will be percent-encoded. - ROC_NODISCARD bool format_encoded_path(core::StringBuilder& dst) const; + ROC_ATTR_NODISCARD bool format_encoded_path(core::StringBuilder& dst) const; private: core::StringBuffer scheme_; @@ -112,7 +112,7 @@ class IoUri : public core::NonCopyable<> { //! //! This parser does not try to perform full URI validation. For example, it does not //! check that path contains only allowed symbols. If it can be parsed, it will be. -ROC_NODISCARD bool parse_io_uri(const char* str, IoUri& result); +bool parse_io_uri(const char* str, IoUri& result); //! Format IoUri to string. //! @@ -125,7 +125,7 @@ ROC_NODISCARD bool parse_io_uri(const char* str, IoUri& result); //! //! @returns //! true on success or false if the buffer is too small. -ROC_NODISCARD bool format_io_uri(const IoUri& uri, core::StringBuilder& dst); +bool format_io_uri(const IoUri& uri, core::StringBuilder& dst); } // namespace address } // namespace roc diff --git a/src/internal_modules/roc_address/io_uri_parse.rl b/src/internal_modules/roc_address/io_uri_parse.rl index d161fd74e..41c22716f 100644 --- a/src/internal_modules/roc_address/io_uri_parse.rl +++ b/src/internal_modules/roc_address/io_uri_parse.rl @@ -99,11 +99,11 @@ bool parse_io_uri_imp(const char* str, IoUri& result) { if (!success) { roc_log(LogError, "parse io uri: expected one of:\n" - " '://',\n" - " 'file://',\n" - " 'file://localhost/',\n" - " 'file:',\n" - " 'file:',\n" + " 'DEVICE_TYPE://DEVICE_NAME',\n" + " 'file:///ABS/PATH',\n" + " 'file://localhost/ABS/PATH',\n" + " 'file:/ABS/PATH',\n" + " 'file:REL/PATH',\n" " 'file://-',\n" " 'file:-',\n" " got '%s'", diff --git a/src/internal_modules/roc_address/io_uri_to_str.cpp b/src/internal_modules/roc_address/io_uri_to_str.cpp index e794b5a53..e36bad741 100644 --- a/src/internal_modules/roc_address/io_uri_to_str.cpp +++ b/src/internal_modules/roc_address/io_uri_to_str.cpp @@ -19,10 +19,7 @@ io_uri_to_str::io_uri_to_str(const IoUri& u) { return; } - if (!format_io_uri(u, b)) { - b.rewrite(""); - return; - } + format_io_uri(u, b); } } // namespace address diff --git a/src/internal_modules/roc_address/network_uri.cpp b/src/internal_modules/roc_address/network_uri.cpp index dc8a9cf36..025940e2b 100644 --- a/src/internal_modules/roc_address/network_uri.cpp +++ b/src/internal_modules/roc_address/network_uri.cpp @@ -26,15 +26,18 @@ bool safe_strcmp(const char* a, const char* b) { } // namespace NetworkUri::NetworkUri(core::IArena& arena) - : non_empty_fields_(0) - , broken_fields_(0) + : invalid_parts_(0) , host_(arena) , path_(arena) , query_(arena) { - clear_fields(FieldsAll); + clear(Subset_Full); } -bool NetworkUri::operator==(const NetworkUri& other) const { +bool NetworkUri::is_equal(const NetworkUri& other) const { + if (invalid_parts_ != 0 || other.invalid_parts_ != 0) { + return false; + } + if (proto() != other.proto()) { return false; } @@ -58,178 +61,139 @@ bool NetworkUri::operator==(const NetworkUri& other) const { return true; } -bool NetworkUri::operator!=(const NetworkUri& other) const { - return !(*this == other); -} +bool NetworkUri::assign(const NetworkUri& other) { + clear(Subset_Full); -bool NetworkUri::is_valid() const { - if (field_state_(FieldProto) != NotEmpty) { - roc_log(LogError, "invalid endpoint uri: missing protocol"); - return false; - } + invalidate(Subset_Full); - if (field_state_(FieldHost) != NotEmpty) { - roc_log(LogError, "invalid endpoint uri: missing host"); + if (!set_proto(other.proto())) { return false; } - const ProtocolAttrs* proto_attrs = ProtocolMap::instance().find_by_id(proto_); - if (!proto_attrs) { - roc_log(LogError, "invalid endpoint uri: unknown protocol"); + if (!set_host(other.host())) { return false; } - if (proto_attrs->default_port > 0) { - if (field_state_(FieldPort) == Broken) { - roc_log(LogError, "invalid endpoint uri: invalid port"); - return false; - } - } else { - if (field_state_(FieldPort) != NotEmpty) { - roc_log(LogError, - "invalid endpoint uri:" - " protocol '%s' requires a port to be specified explicitly," - " but it is omitted in the uri", - proto_to_str(proto_)); - return false; - } + if (!set_port(other.port())) { + return false; } - if (field_state_(FieldPath) == Broken) { - roc_log(LogError, "invalid endpoint uri: invalid path"); + if (!set_path(other.path())) { return false; } - if (field_state_(FieldQuery) == Broken) { - roc_log(LogError, "invalid endpoint uri: invalid query"); + + if (!set_encoded_query(other.encoded_query())) { return false; } - if (!proto_attrs->path_supported) { - if (field_state_(FieldPath) != Empty || field_state_(FieldQuery) != Empty) { - roc_log(LogError, - "invalid endpoint uri:" - " protocol '%s' forbids using a path and query," - " but they are present in the uri", - proto_to_str(proto_)); - return false; - } - } return true; } -bool NetworkUri::has_fields(int fields_mask) const { - for (size_t n = 0; n < sizeof(fields_mask) * 8; n++) { - if ((fields_mask & (int)n) && field_state_((Field)n) != NotEmpty) { +bool NetworkUri::verify(Subset subset) const { + if (subset == Subset_Resource) { + if ((invalid_parts_ & (PartPath | PartQuery)) != 0) { + roc_log(LogError, "invalid endpoint uri: contains invalid parts"); return false; } - } - return true; -} + return true; + } -void NetworkUri::clear_fields(int fields_mask) { - if (fields_mask & FieldProto) { - set_field_state_(FieldProto, Empty); - proto_ = Proto_None; + if (invalid_parts_ != 0) { + roc_log(LogError, "invalid endpoint uri: contains invalid parts"); + return false; } - if (fields_mask & FieldHost) { - set_field_state_(FieldHost, Empty); - host_.clear(); + if (service_[0] == '\0') { + roc_log(LogError, "invalid endpoint uri: unknown service"); + return false; } - if (fields_mask & FieldPort) { - set_field_state_(FieldPort, Empty); - port_ = -1; + const ProtocolAttrs* proto_attrs = ProtocolMap::instance().find_by_id(proto_); + if (!proto_attrs) { + roc_log(LogError, "invalid endpoint uri: unknown protocol"); + return false; } - if (fields_mask & FieldPath) { - set_field_state_(FieldPath, Empty); - path_.clear(); + if (port_ < 0 && proto_attrs->default_port < 0) { + roc_log(LogError, + "invalid endpoint uri:" + " protocol '%s' requires a port to be specified explicitly," + " but it is omitted in the uri", + proto_to_str(proto_)); + return false; } - if (fields_mask & FieldQuery) { - set_field_state_(FieldQuery, Empty); - query_.clear(); + if (!proto_attrs->path_supported) { + if (!path_.is_empty() || !query_.is_empty()) { + roc_log(LogError, + "invalid endpoint uri:" + " protocol '%s' forbids using a path and query," + " but they are present in the uri", + proto_to_str(proto_)); + return false; + } } + + return true; } -void NetworkUri::invalidate_fields(int fields_mask) { - if (fields_mask & FieldProto) { - set_field_state_(FieldProto, Broken); +void NetworkUri::clear(Subset subset) { + if (subset == Subset_Full) { + invalid_parts_ |= PartProto; proto_ = Proto_None; - } - if (fields_mask & FieldHost) { - set_field_state_(FieldHost, Broken); + invalid_parts_ |= PartHost; host_.clear(); - } - if (fields_mask & FieldPort) { - set_field_state_(FieldPort, Broken); + invalid_parts_ |= PartPort; port_ = -1; + service_[0] = '\0'; } - if (fields_mask & FieldPath) { - set_field_state_(FieldPath, Broken); - path_.clear(); - } + invalid_parts_ &= ~PartPath; + path_.clear(); - if (fields_mask & FieldQuery) { - set_field_state_(FieldQuery, Broken); - query_.clear(); - } + invalid_parts_ &= ~PartQuery; + query_.clear(); } -bool NetworkUri::assign(const NetworkUri& other) { - clear_fields(FieldsAll); - - if (!set_proto(other.proto())) { - return false; - } - - if (!set_host(other.host())) { - return false; +void NetworkUri::invalidate(Subset subset) { + if (subset == Subset_Full) { + invalid_parts_ |= (PartProto | PartHost | PartPort); } - - if (!set_port(other.port())) { - return false; - } - - if (!set_path(other.path())) { - return false; - } - - if (!set_encoded_query(other.encoded_query())) { - return false; - } - - return true; + invalid_parts_ |= (PartPath | PartQuery); } bool NetworkUri::set_proto(Protocol proto) { if (ProtocolMap::instance().find_by_id(proto) == NULL) { - proto_ = Proto_None; - set_field_state_(FieldProto, Broken); + set_invalid_(PartProto); return false; } proto_ = proto; - set_field_state_(FieldProto, NotEmpty); + if (port_ == -1) { + if (set_service_from_proto_(proto)) { + set_valid_(PartPort); + } else { + set_invalid_(PartPort); + } + } + + set_valid_(PartProto); return true; } Protocol NetworkUri::proto() const { - if (field_state_(FieldProto) != NotEmpty) { + if (!part_is_valid_(PartProto)) { return Proto_None; } - return proto_; } bool NetworkUri::get_proto(Protocol& proto) const { - if (field_state_(FieldProto) != NotEmpty) { + if (!part_is_valid_(PartProto)) { return false; } @@ -238,7 +202,7 @@ bool NetworkUri::get_proto(Protocol& proto) const { } bool NetworkUri::format_proto(core::StringBuilder& dst) const { - if (field_state_(FieldProto) != NotEmpty) { + if (!part_is_valid_(PartProto)) { return false; } @@ -253,8 +217,7 @@ bool NetworkUri::format_proto(core::StringBuilder& dst) const { bool NetworkUri::set_host(const char* str) { if (!str) { - host_.clear(); - set_field_state_(FieldHost, Broken); + set_invalid_(PartHost); return false; } @@ -262,66 +225,74 @@ bool NetworkUri::set_host(const char* str) { } bool NetworkUri::set_host(const char* str, size_t str_len) { - if (!str || str_len == 0) { - host_.clear(); - set_field_state_(FieldHost, Broken); + if (!str) { + set_invalid_(PartHost); return false; } if (!host_.assign(str, str + str_len) || host_.is_empty()) { - host_.clear(); - set_field_state_(FieldHost, Broken); + set_invalid_(PartHost); return false; } - set_field_state_(FieldHost, NotEmpty); + set_valid_(PartHost); return true; } const char* NetworkUri::host() const { - if (field_state_(FieldHost) != NotEmpty) { + if (!part_is_valid_(PartHost)) { return ""; } return host_.c_str(); } bool NetworkUri::format_host(core::StringBuilder& dst) const { - if (field_state_(FieldHost) != NotEmpty) { + if (!part_is_valid_(PartHost)) { return false; } - dst.append_str(host_.c_str()); return true; } bool NetworkUri::set_port(int port) { - if (port == DefautPort) { - port_ = DefautPort; - set_field_state_(FieldPort, Empty); + if (port == -1) { + port_ = -1; + + if (part_is_valid_(PartProto)) { + if (set_service_from_proto_(proto_)) { + set_valid_(PartPort); + } else { + set_invalid_(PartPort); + } + } else { + set_invalid_(PartPort); + } + return true; } if (port < 0 || port > 65535) { - port_ = DefautPort; - set_field_state_(FieldPort, Broken); + set_invalid_(PartPort); return false; } port_ = port; - set_field_state_(FieldPort, NotEmpty); + + set_service_from_port_(port); + set_valid_(PartPort); + return true; } int NetworkUri::port() const { - if (field_state_(FieldPort) != NotEmpty) { - return DefautPort; + if (!part_is_valid_(PartPort)) { + return -1; } - return port_; } bool NetworkUri::get_port(int& port) const { - if (field_state_(FieldPort) != NotEmpty) { + if (!part_is_valid_(PartPort) || port_ == -1) { return false; } @@ -329,174 +300,164 @@ bool NetworkUri::get_port(int& port) const { return true; } -int NetworkUri::port_or_default() const { - if (field_state_(FieldPort) == NotEmpty) { - return port_; +const char* NetworkUri::service() const { + if (service_[0]) { + return service_; } - - if (field_state_(FieldProto) == NotEmpty) { - const ProtocolAttrs* attrs = ProtocolMap::instance().find_by_id(proto_); - if (attrs) { - if (attrs->default_port > 0) { - return attrs->default_port; - } - } - } - - return DefautPort; + return NULL; } bool NetworkUri::set_path(const char* str) { if (!str) { path_.clear(); - set_field_state_(FieldPath, Broken); - return false; + set_valid_(PartPath); + return true; } return set_path(str, strlen(str)); } bool NetworkUri::set_path(const char* str, size_t str_len) { - if (!str) { + if (!str || str_len < 1) { path_.clear(); - set_field_state_(FieldPath, Broken); - return false; + set_valid_(PartPath); + return true; } if (!path_.assign(str, str + str_len)) { - path_.clear(); - set_field_state_(FieldPath, Broken); + set_invalid_(PartPath); return false; } - set_field_state_(FieldPath, str_len > 0 ? NotEmpty : Empty); + set_valid_(PartPath); return true; } bool NetworkUri::set_encoded_path(const char* str) { if (!str) { path_.clear(); - set_field_state_(FieldPath, Broken); - return false; + set_valid_(PartPath); + return true; } return set_encoded_path(str, strlen(str)); } bool NetworkUri::set_encoded_path(const char* str, size_t str_len) { - if (!str) { + if (!str || str_len < 1) { path_.clear(); - set_field_state_(FieldPath, Broken); - return false; + set_valid_(PartPath); + return true; } if (!path_.grow(str_len)) { - path_.clear(); - set_field_state_(FieldPath, Broken); + set_invalid_(PartPath); return false; } core::StringBuilder b(path_); if (!pct_decode(b, str, str_len)) { - path_.clear(); - set_field_state_(FieldPath, Broken); + set_invalid_(PartPath); return false; } if (!b.is_ok()) { - path_.clear(); - set_field_state_(FieldPath, Broken); + set_invalid_(PartPath); return false; } - set_field_state_(FieldPath, str_len > 0 ? NotEmpty : Empty); + set_valid_(PartPath); return true; } const char* NetworkUri::path() const { - if (field_state_(FieldPath) != NotEmpty) { + if (!part_is_valid_(PartPath) || path_.is_empty()) { return NULL; } return path_.c_str(); } bool NetworkUri::format_encoded_path(core::StringBuilder& dst) const { - if (field_state_(FieldPath) != NotEmpty) { + if (!part_is_valid_(PartPath) || path_.is_empty()) { return false; } - return pct_encode(dst, path_.c_str(), path_.len(), PctNonPath); } bool NetworkUri::set_encoded_query(const char* str) { if (!str) { query_.clear(); - set_field_state_(FieldQuery, Broken); - return false; + set_valid_(PartQuery); + return true; } return set_encoded_query(str, strlen(str)); } bool NetworkUri::set_encoded_query(const char* str, size_t str_len) { - if (!str) { + if (!str || str_len < 1) { query_.clear(); - set_field_state_(FieldQuery, Broken); - return false; + set_valid_(PartQuery); + return true; } if (!query_.assign(str, str + str_len)) { - query_.clear(); - set_field_state_(FieldQuery, Broken); + set_invalid_(PartQuery); return false; } - set_field_state_(FieldQuery, str_len > 0 ? NotEmpty : Empty); + set_valid_(PartQuery); return true; } const char* NetworkUri::encoded_query() const { - if (field_state_(FieldQuery) != NotEmpty) { + if (!part_is_valid_(PartQuery) || query_.is_empty()) { return NULL; } - return query_.c_str(); } bool NetworkUri::format_encoded_query(core::StringBuilder& dst) const { - if (field_state_(FieldQuery) != NotEmpty) { + if (!part_is_valid_(PartQuery) || query_.is_empty()) { return false; } - dst.append_str(query_.c_str()); return true; } -NetworkUri::FieldState NetworkUri::field_state_(Field field) const { - if (broken_fields_ & field) { - return Broken; - } +void NetworkUri::set_service_from_port_(int port) { + core::StringBuilder b(service_, sizeof(service_)); - if (non_empty_fields_ & field) { - return NotEmpty; + if (!b.append_uint((uint64_t)port, 10)) { + roc_panic("endpoint uri: can't format port to string"); } - - return Empty; } -void NetworkUri::set_field_state_(Field field, FieldState state) { - if (state == Broken) { - broken_fields_ |= field; - } else { - broken_fields_ &= ~field; +bool NetworkUri::set_service_from_proto_(Protocol proto) { + const ProtocolAttrs* attrs = ProtocolMap::instance().find_by_id(proto); + if (!attrs) { + return false; } - if (state == NotEmpty) { - non_empty_fields_ |= field; - } else { - non_empty_fields_ &= ~field; + if (attrs->default_port <= 0) { + return false; } + + set_service_from_port_(attrs->default_port); + return true; +} + +bool NetworkUri::part_is_valid_(Part part) const { + return (invalid_parts_ & part) == 0; +} + +void NetworkUri::set_valid_(Part part) { + invalid_parts_ &= ~part; +} + +void NetworkUri::set_invalid_(Part part) { + invalid_parts_ |= part; } } // namespace address diff --git a/src/internal_modules/roc_address/network_uri.h b/src/internal_modules/roc_address/network_uri.h index c4f1636ae..97f57a824 100644 --- a/src/internal_modules/roc_address/network_uri.h +++ b/src/internal_modules/roc_address/network_uri.h @@ -26,165 +26,142 @@ namespace address { //! Network endpoint URI. class NetworkUri : public core::NonCopyable<> { public: - //! URI field. - enum Field { - FieldProto = (1 << 0), //!< Scheme. - FieldHost = (1 << 1), //!< Host. - FieldPort = (1 << 2), //!< Optional port number. - FieldPath = (1 << 3), //!< Optional path. - FieldQuery = (1 << 4), //!< Optional query. - - //! Full URI. - FieldsAll = FieldProto | FieldHost | FieldPort | FieldPath | FieldQuery, - //! Resource part of the URI. - FieldsResource = FieldPath | FieldQuery, + //! URI subset. + enum Subset { + Subset_Full, //!< Entire URI. + Subset_Resource //!< Absolute path and query. }; //! Initialize empty URI. explicit NetworkUri(core::IArena& arena); //! Check if URI is equivalent to another URI. - bool operator==(const NetworkUri& other) const; - - //! Check if URI is equivalent to another URI. - bool operator!=(const NetworkUri& other) const; - - //! Check validity of the URI. - //! @remarks - //! URI is valid if: - //! - No fields are invalidated. - //! - All required fields are present: protocol. host, and probably port: - //! whether port is required depends on protocol. - //! - No forbidden fields are present: whether path and query are allowed - //! depends on protocol. - //! @note - //! Fields are invalidated explicitly by invalidate_fields() call, and - //! implicitly when a setter for that field fails. - bool is_valid() const; - - //! Check if all of the fields from mask are present. - //! @p field_mask is a bitmask of values from Field enum. - bool has_fields(int fields_mask) const; - - //! Clear given fields of the URI. - //! @p field_mask is a bitmask of values from Field enum. - void clear_fields(int fields_mask); - - //! Mark given fields as invalid. - //! @p field_mask is a bitmask of values from Field enum. - void invalidate_fields(int fields_mask); + bool is_equal(const NetworkUri& other) const; //! Copy data from another URI. - ROC_NODISCARD bool assign(const NetworkUri& other); + ROC_ATTR_NODISCARD bool assign(const NetworkUri& other); + + //! Check given subset of the URI. + bool verify(Subset subset) const; + + //! Clear given subset of the URI. + void clear(Subset subset); + + //! Invalidate given subset of the URI. + void invalidate(Subset subset); //! Set protocol ID (URI scheme). - ROC_NODISCARD bool set_proto(Protocol); + ROC_ATTR_NODISCARD bool set_proto(Protocol); //! Protocol ID (URI scheme). Protocol proto() const; //! Get protocol ID (URI scheme). - ROC_NODISCARD bool get_proto(Protocol& proto) const; + ROC_ATTR_NODISCARD bool get_proto(Protocol& proto) const; //! Get URI proto. - ROC_NODISCARD bool format_proto(core::StringBuilder& dst) const; + ROC_ATTR_NODISCARD bool format_proto(core::StringBuilder& dst) const; //! Set URI host. //! String should be zero-terminated. - ROC_NODISCARD bool set_host(const char* str); + ROC_ATTR_NODISCARD bool set_host(const char* str); //! Set URI host. //! String should not be zero-terminated. - ROC_NODISCARD bool set_host(const char* str, size_t str_len); + ROC_ATTR_NODISCARD bool set_host(const char* str, size_t str_len); //! Hostname or IP address. const char* host() const; //! Get URI host. - ROC_NODISCARD bool format_host(core::StringBuilder& dst) const; - - enum { - //! Use default port number defined by protocol. - DefautPort = -1 - }; + ROC_ATTR_NODISCARD bool format_host(core::StringBuilder& dst) const; //! Set port. - ROC_NODISCARD bool set_port(int port); + ROC_ATTR_NODISCARD bool set_port(int); //! TCP or UDP port. int port() const; //! Get URI port. - ROC_NODISCARD bool get_port(int& port) const; + ROC_ATTR_NODISCARD bool get_port(int& port) const; - //! Get port number, or default port number if port isn't set. - int port_or_default() const; + //! Get string representation of port. + //! If port is not set, default port for the protocol is used. + //! This string is suitable for passing to getaddrinfo(). + //! @returns NULL if both port and default port are not set. + const char* service() const; //! Set decoded URI path. - ROC_NODISCARD bool set_path(const char* str); + ROC_ATTR_NODISCARD bool set_path(const char* str); //! Set decoded URI path. //! String should not be zero-terminated. - ROC_NODISCARD bool set_path(const char* str, size_t str_len); + ROC_ATTR_NODISCARD bool set_path(const char* str, size_t str_len); //! Set encoded URI path. //! String should be percent-encoded. - ROC_NODISCARD bool set_encoded_path(const char* str); + ROC_ATTR_NODISCARD bool set_encoded_path(const char* str); //! Set encoded URI path. //! String should be percent-encoded. //! String should not be zero-terminated. - ROC_NODISCARD bool set_encoded_path(const char* str, size_t str_len); + ROC_ATTR_NODISCARD bool set_encoded_path(const char* str, size_t str_len); //! Decoded path. const char* path() const; //! Get URI path. //! String will be percent-encoded. - ROC_NODISCARD bool format_encoded_path(core::StringBuilder& dst) const; + ROC_ATTR_NODISCARD bool format_encoded_path(core::StringBuilder& dst) const; //! Set query. //! String should be percent-encoded. - ROC_NODISCARD bool set_encoded_query(const char* str); + ROC_ATTR_NODISCARD bool set_encoded_query(const char* str); //! Set query. //! String should be percent-encoded. //! String should not be zero-terminated. - ROC_NODISCARD bool set_encoded_query(const char* str, size_t str_len); + ROC_ATTR_NODISCARD bool set_encoded_query(const char* str, size_t str_len); //! Raw query. const char* encoded_query() const; //! Get URI query. //! String will be percent-encoded. - ROC_NODISCARD bool format_encoded_query(core::StringBuilder& dst) const; + ROC_ATTR_NODISCARD bool format_encoded_query(core::StringBuilder& dst) const; private: - enum FieldState { - NotEmpty, - Empty, - Broken, + void set_service_from_port_(int port); + bool set_service_from_proto_(Protocol proto); + + enum Part { + PartProto = (1 << 0), + PartHost = (1 << 1), + PartPort = (1 << 2), + PartPath = (1 << 3), + PartQuery = (1 << 4) }; - FieldState field_state_(Field field) const; - void set_field_state_(Field field, FieldState state); + bool part_is_valid_(Part part) const; + void set_valid_(Part part); + void set_invalid_(Part part); - int non_empty_fields_; - int broken_fields_; + int invalid_parts_; Protocol proto_; + core::StringBuffer host_; int port_; + char service_[6]; + core::StringBuffer path_; core::StringBuffer query_; }; -//! Parse network URI. +//! Parse NetworkUri from string. //! //! The URI should be in the following form: -//! @code -//! ://[:][/][?] -//! @endcode +//! - PROTOCOL://HOST[:PORT][/PATH][?QUERY] //! //! Examples: //! - rtp+rs8m://localhost @@ -207,16 +184,10 @@ class NetworkUri : public core::NonCopyable<> { //! //! This parser does not try to perform full URI validation. For example, it does not //! check that path contains only allowed symbols. If it can be parsed, it will be. -ROC_NODISCARD bool parse_network_uri(const char* str, NetworkUri& result); - -//! Parse resource part of network URI. -//! -//! Same as parse_network_uri(), but parses only path and query. -//! Keeps other fields untouched. -//! Fails if string contains anything besides path and query. -ROC_NODISCARD bool parse_network_uri_resource(const char* str, NetworkUri& result); +ROC_ATTR_NODISCARD bool +parse_network_uri(const char* str, NetworkUri::Subset subset, NetworkUri& result); -//! Format network URI. +//! Format NetworkUri to string. //! //! Formats a normalized form of the URI. //! @@ -225,14 +196,9 @@ ROC_NODISCARD bool parse_network_uri_resource(const char* str, NetworkUri& resul //! //! @returns //! true on success or false if the buffer is too small. -ROC_NODISCARD bool format_network_uri(const NetworkUri& uri, core::StringBuilder& dst); - -//! Format resource part of network URI. -//! -//! Same as format_network_uri(), but formats only path and query. -//! Ignores other fields. -ROC_NODISCARD bool format_network_uri_resource(const NetworkUri& uri, - core::StringBuilder& dst); +ROC_ATTR_NODISCARD bool format_network_uri(const NetworkUri& uri, + NetworkUri::Subset subset, + core::StringBuilder& dst); } // namespace address } // namespace roc diff --git a/src/internal_modules/roc_address/network_uri_format.cpp b/src/internal_modules/roc_address/network_uri_format.cpp index e28aa2eb5..a527e86bd 100644 --- a/src/internal_modules/roc_address/network_uri_format.cpp +++ b/src/internal_modules/roc_address/network_uri_format.cpp @@ -13,16 +13,14 @@ namespace roc { namespace address { -namespace { - -bool format_network_uri_imp(const NetworkUri& u, - core::StringBuilder& dst, - bool only_resource) { - if (!only_resource) { - if (!u.is_valid()) { - return false; - } +bool format_network_uri(const NetworkUri& u, + NetworkUri::Subset subset, + core::StringBuilder& dst) { + if (!u.verify(subset)) { + return false; + } + if (subset == NetworkUri::Subset_Full) { if (!u.format_proto(dst)) { return false; } @@ -39,7 +37,7 @@ bool format_network_uri_imp(const NetworkUri& u, } } - if (only_resource) { + if (subset == NetworkUri::Subset_Resource) { if (!u.path() && !u.encoded_query()) { return false; } @@ -61,15 +59,5 @@ bool format_network_uri_imp(const NetworkUri& u, return true; } -} // namespace - -bool format_network_uri(const NetworkUri& u, core::StringBuilder& dst) { - return format_network_uri_imp(u, dst, false); -} - -bool format_network_uri_resource(const NetworkUri& u, core::StringBuilder& dst) { - return format_network_uri_imp(u, dst, true); -} - } // namespace address } // namespace roc diff --git a/src/internal_modules/roc_address/network_uri_parse.rl b/src/internal_modules/roc_address/network_uri_parse.rl index c782c4c34..1d2eb8480 100644 --- a/src/internal_modules/roc_address/network_uri_parse.rl +++ b/src/internal_modules/roc_address/network_uri_parse.rl @@ -21,17 +21,19 @@ namespace address { namespace { -bool parse_network_uri_imp(const char* str, NetworkUri& result, bool only_resource) { +bool parse_network_uri_imp(const char* str, NetworkUri::Subset subset, NetworkUri& result) { if (!str) { roc_log(LogError, "parse endpoint uri: input string is null"); return false; } + result.clear(subset); + // for ragel const char* p = str; - const char* pe = str + strlen(str); + const char *pe = str + strlen(str); - const char* eof = pe; + const char *eof = pe; int cs = 0; // for actions @@ -47,12 +49,6 @@ bool parse_network_uri_imp(const char* str, NetworkUri& result, bool only_resour } action set_proto { - if (only_resource) { - roc_log(LogError, - "parse endpoint uri: protocol field not allowed"); - return false; - } - char scheme[16] = {}; if (p - start_p >= sizeof(scheme)) { roc_log(LogError, "parse endpoint uri: invalid protocol"); @@ -73,12 +69,11 @@ bool parse_network_uri_imp(const char* str, NetworkUri& result, bool only_resour } action set_host { - if (only_resource) { + if (subset != NetworkUri::Subset_Full) { roc_log(LogError, - "parse endpoint uri: protocol field not allowed"); + "parse endpoint uri: unexpected host when parsing resource"); return false; } - if (!result.set_host(start_p, p - start_p)) { roc_log(LogError, "parse endpoint uri: invalid host"); return false; @@ -86,9 +81,9 @@ bool parse_network_uri_imp(const char* str, NetworkUri& result, bool only_resour } action set_port { - if (only_resource) { + if (subset != NetworkUri::Subset_Full) { roc_log(LogError, - "parse endpoint uri: port field not allowed"); + "parse endpoint uri: unexpected port when parsing resource"); return false; } @@ -140,47 +135,38 @@ bool parse_network_uri_imp(const char* str, NetworkUri& result, bool only_resour write exec; }%% - return success; -} - -} // namespace - -bool parse_network_uri(const char* str, NetworkUri& result) { - result.clear_fields(NetworkUri::FieldsAll); - - const bool success = parse_network_uri_imp(str, result, false); - - if (!success || !result.is_valid()) { - roc_log(LogError, - "parse endpoint uri: expected" - " '://[:][/][?]',\n" - " got '%s'", - str); + if (!success) { + if (subset == NetworkUri::Subset_Full) { + roc_log(LogError, + "parse endpoint uri: expected" + " 'PROTO://HOST[:PORT][/PATH][?QUERY]',\n" + " got '%s'", + str); + } else { + roc_log(LogError, + "parse endpoint uri: expected" + " '[/PATH][?QUERY]',\n" + " got '%s'", + str); + } return false; + } - result.invalidate_fields(NetworkUri::FieldsAll); + if (!result.verify(subset)) { + roc_log(LogError, "parse endpoint uri: invalid uri"); return false; } return true; } -bool parse_network_uri_resource(const char* str, NetworkUri& result) { - result.clear_fields(NetworkUri::FieldsResource); - - const bool success = parse_network_uri_imp(str, result, true); - - if (!success) { - roc_log(LogError, - "parse endpoint uri: expected" - " '[/][?]',\n" - " got '%s'", - str); +} // namespace - result.invalidate_fields(NetworkUri::FieldsResource); +bool parse_network_uri(const char* str, NetworkUri::Subset subset, NetworkUri& result) { + if (!parse_network_uri_imp(str, subset, result)) { + result.invalidate(subset); return false; } - return true; } diff --git a/src/internal_modules/roc_address/network_uri_to_str.cpp b/src/internal_modules/roc_address/network_uri_to_str.cpp index 696745ec2..04b6c827f 100644 --- a/src/internal_modules/roc_address/network_uri_to_str.cpp +++ b/src/internal_modules/roc_address/network_uri_to_str.cpp @@ -15,12 +15,12 @@ namespace address { network_uri_to_str::network_uri_to_str(const NetworkUri& u) { core::StringBuilder b(buf_, sizeof(buf_)); - if (!u.is_valid()) { + if (!u.verify(NetworkUri::Subset_Full)) { b.rewrite(""); return; } - if (!format_network_uri(u, b)) { + if (!format_network_uri(u, NetworkUri::Subset_Full, b)) { b.rewrite(""); return; } diff --git a/src/internal_modules/roc_address/parse_socket_addr.h b/src/internal_modules/roc_address/parse_socket_addr.h index 2b95dc207..08cfd8a35 100644 --- a/src/internal_modules/roc_address/parse_socket_addr.h +++ b/src/internal_modules/roc_address/parse_socket_addr.h @@ -27,7 +27,7 @@ namespace address { //! //! @returns //! false if @p host can't be parsed. -ROC_NODISCARD bool parse_socket_addr(const char* host, int port, SocketAddr& addr); +ROC_ATTR_NODISCARD bool parse_socket_addr(const char* host, int port, SocketAddr& addr); } // namespace address } // namespace roc diff --git a/src/internal_modules/roc_address/pct.h b/src/internal_modules/roc_address/pct.h index ebbbd7c3a..5c81625da 100644 --- a/src/internal_modules/roc_address/pct.h +++ b/src/internal_modules/roc_address/pct.h @@ -42,7 +42,7 @@ enum PctMode { //! @remarks //! The source string should NOT be null-terminated. //! The source string size should NOT include the terminating zero byte. -ROC_NODISCARD bool +ROC_ATTR_NODISCARD bool pct_encode(core::StringBuilder& dst, const char* src, size_t src_sz, PctMode mode); //! Percent-decode an UTF-8 string. @@ -55,7 +55,8 @@ pct_encode(core::StringBuilder& dst, const char* src, size_t src_sz, PctMode mod //! @remarks //! The source string should NOT be null-terminated. //! The source string size should NOT include the terminating zero byte. -ROC_NODISCARD bool pct_decode(core::StringBuilder& dst, const char* src, size_t src_sz); +ROC_ATTR_NODISCARD bool +pct_decode(core::StringBuilder& dst, const char* src, size_t src_sz); } // namespace address } // namespace roc diff --git a/src/internal_modules/roc_address/protocol_map.h b/src/internal_modules/roc_address/protocol_map.h index d695019d4..c72327c41 100644 --- a/src/internal_modules/roc_address/protocol_map.h +++ b/src/internal_modules/roc_address/protocol_map.h @@ -69,10 +69,10 @@ class ProtocolMap : public core::NonCopyable<> { const ProtocolAttrs* find_by_scheme(const char* scheme) const; //! Get list of interfaces with at least one protocol. - ROC_NODISCARD bool get_supported_interfaces(core::Array&); + ROC_ATTR_NODISCARD bool get_supported_interfaces(core::Array&); //! Get all supported protocols. - ROC_NODISCARD bool get_supported_protocols(Interface, core::StringList&); + ROC_ATTR_NODISCARD bool get_supported_protocols(Interface, core::StringList&); private: friend class core::Singleton; diff --git a/src/internal_modules/roc_address/target_posix/roc_address/socket_addr.cpp b/src/internal_modules/roc_address/target_posix/roc_address/socket_addr.cpp index de3585886..6e7767d93 100644 --- a/src/internal_modules/roc_address/target_posix/roc_address/socket_addr.cpp +++ b/src/internal_modules/roc_address/target_posix/roc_address/socket_addr.cpp @@ -117,7 +117,7 @@ int SocketAddr::port() const { } } -bool SocketAddr::is_multicast() const { +bool SocketAddr::multicast() const { switch (saddr_family_()) { case AF_INET: return IN_MULTICAST(core::ntoh32u(saddr_.addr4.sin_addr.s_addr)); diff --git a/src/internal_modules/roc_address/target_posix/roc_address/socket_addr.h b/src/internal_modules/roc_address/target_posix/roc_address/socket_addr.h index 8b3bc00d7..008418aa0 100644 --- a/src/internal_modules/roc_address/target_posix/roc_address/socket_addr.h +++ b/src/internal_modules/roc_address/target_posix/roc_address/socket_addr.h @@ -35,22 +35,22 @@ class SocketAddr { bool has_host_port() const; //! Set host address. - ROC_NODISCARD bool set_host_port(AddrFamily type, const char* host, int port); + ROC_ATTR_NODISCARD bool set_host_port(AddrFamily type, const char* host, int port); //! Set host address, auto-detect family. - ROC_NODISCARD bool set_host_port_auto(const char* host, int port); + ROC_ATTR_NODISCARD bool set_host_port_auto(const char* host, int port); //! Set address from sockaddr struct. - ROC_NODISCARD bool set_host_port_saddr(const sockaddr* sa); + ROC_ATTR_NODISCARD bool set_host_port_saddr(const sockaddr* sa); //! Get IP version (IPv4 or IPv6). AddrFamily family() const; //! Check whether this is multicast address. - bool is_multicast() const; + bool multicast() const; //! Get host IP address. - ROC_NODISCARD bool get_host(char* buf, size_t bufsz) const; + ROC_ATTR_NODISCARD bool get_host(char* buf, size_t bufsz) const; //! Get address port. int port() const; diff --git a/src/internal_modules/roc_audio/channel_mapper_reader.h b/src/internal_modules/roc_audio/channel_mapper_reader.h index 0572984d8..a762a3c46 100644 --- a/src/internal_modules/roc_audio/channel_mapper_reader.h +++ b/src/internal_modules/roc_audio/channel_mapper_reader.h @@ -38,7 +38,7 @@ class ChannelMapperReader : public IFrameReader, public core::NonCopyable<> { status::StatusCode init_status() const; //! Read audio frame. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode read(Frame& frame, packet::stream_timestamp_t duration, FrameReadMode mode); private: diff --git a/src/internal_modules/roc_audio/channel_mapper_writer.h b/src/internal_modules/roc_audio/channel_mapper_writer.h index ccdf714f6..79faec075 100644 --- a/src/internal_modules/roc_audio/channel_mapper_writer.h +++ b/src/internal_modules/roc_audio/channel_mapper_writer.h @@ -38,7 +38,7 @@ class ChannelMapperWriter : public IFrameWriter, public core::NonCopyable<> { status::StatusCode init_status() const; //! Write audio frame. - virtual ROC_NODISCARD status::StatusCode write(Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(Frame& frame); private: FrameFactory& frame_factory_; diff --git a/src/internal_modules/roc_audio/depacketizer.h b/src/internal_modules/roc_audio/depacketizer.h index 1ef9dad52..9f9d456d8 100644 --- a/src/internal_modules/roc_audio/depacketizer.h +++ b/src/internal_modules/roc_audio/depacketizer.h @@ -113,7 +113,7 @@ class Depacketizer : public IFrameReader, public core::NonCopyable<> { packet::stream_timestamp_t next_timestamp() const; //! Read audio frame. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode read(Frame& frame, packet::stream_timestamp_t duration, FrameReadMode mode); private: diff --git a/src/internal_modules/roc_audio/fanout.h b/src/internal_modules/roc_audio/fanout.h index 04d8b2819..041a13200 100644 --- a/src/internal_modules/roc_audio/fanout.h +++ b/src/internal_modules/roc_audio/fanout.h @@ -46,7 +46,7 @@ class Fanout : public IFrameWriter, public core::NonCopyable<> { bool has_output(IFrameWriter& writer); //! Add output writer. - ROC_NODISCARD status::StatusCode add_output(IFrameWriter& writer); + ROC_ATTR_NODISCARD status::StatusCode add_output(IFrameWriter& writer); //! Remove output writer. void remove_output(IFrameWriter& writer); @@ -54,7 +54,7 @@ class Fanout : public IFrameWriter, public core::NonCopyable<> { //! Write audio frame. //! @remarks //! Writes samples to every output writer. - virtual ROC_NODISCARD status::StatusCode write(Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(Frame& frame); private: struct Output { diff --git a/src/internal_modules/roc_audio/feedback_monitor.h b/src/internal_modules/roc_audio/feedback_monitor.h index f4fc8dbb3..fb40a426f 100644 --- a/src/internal_modules/roc_audio/feedback_monitor.h +++ b/src/internal_modules/roc_audio/feedback_monitor.h @@ -90,7 +90,7 @@ class FeedbackMonitor : public IFrameWriter, public core::NonCopyable<> { //! Write audio frame. //! Passes frame to underlying writer. //! If feedback monitoring is started, also performs latency tuning. - virtual ROC_NODISCARD status::StatusCode write(Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(Frame& frame); //! Get number of remote participants from which there is feedback. size_t num_participants() const; diff --git a/src/internal_modules/roc_audio/freq_estimator.h b/src/internal_modules/roc_audio/freq_estimator.h index 796be0bb7..009294cca 100644 --- a/src/internal_modules/roc_audio/freq_estimator.h +++ b/src/internal_modules/roc_audio/freq_estimator.h @@ -63,7 +63,7 @@ struct FreqEstimatorConfig { } //! Automatically fill missing settings. - ROC_NODISCARD bool deduce_defaults(LatencyTunerProfile latency_profile); + ROC_ATTR_NODISCARD bool deduce_defaults(LatencyTunerProfile latency_profile); }; //! Evaluates sender's frequency to receiver's frequency ratio. diff --git a/src/internal_modules/roc_audio/iframe_reader.h b/src/internal_modules/roc_audio/iframe_reader.h index 6d815424f..ee19fae7d 100644 --- a/src/internal_modules/roc_audio/iframe_reader.h +++ b/src/internal_modules/roc_audio/iframe_reader.h @@ -76,7 +76,7 @@ class IFrameReader : public core::ListNode<> { //! - Otherwise, returns an error. //! //! @see status::StatusCode. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode read(Frame& frame, packet::stream_timestamp_t duration, FrameReadMode mode) = 0; }; diff --git a/src/internal_modules/roc_audio/iframe_writer.h b/src/internal_modules/roc_audio/iframe_writer.h index 0200ca38a..22d7e8961 100644 --- a/src/internal_modules/roc_audio/iframe_writer.h +++ b/src/internal_modules/roc_audio/iframe_writer.h @@ -40,7 +40,7 @@ class IFrameWriter : public core::ListNode<> { //! were written or not, and no further writes are expected. //! //! @see status::StatusCode. - virtual ROC_NODISCARD status::StatusCode write(Frame& frame) = 0; + virtual ROC_ATTR_NODISCARD status::StatusCode write(Frame& frame) = 0; }; } // namespace audio diff --git a/src/internal_modules/roc_audio/jitter_meter.h b/src/internal_modules/roc_audio/jitter_meter.h index f81ed59dc..d17608f59 100644 --- a/src/internal_modules/roc_audio/jitter_meter.h +++ b/src/internal_modules/roc_audio/jitter_meter.h @@ -104,7 +104,7 @@ struct JitterMeterConfig { } //! Automatically fill missing settings. - ROC_NODISCARD bool deduce_defaults(audio::LatencyTunerProfile latency_profile); + ROC_ATTR_NODISCARD bool deduce_defaults(audio::LatencyTunerProfile latency_profile); }; //! Jitter metrics. diff --git a/src/internal_modules/roc_audio/latency_config.h b/src/internal_modules/roc_audio/latency_config.h index 0979492f4..e6fb46529 100644 --- a/src/internal_modules/roc_audio/latency_config.h +++ b/src/internal_modules/roc_audio/latency_config.h @@ -186,8 +186,8 @@ struct LatencyConfig { } //! Automatically fill missing settings. - ROC_NODISCARD bool deduce_defaults(core::nanoseconds_t default_latency, - bool is_receiver); + ROC_ATTR_NODISCARD bool deduce_defaults(core::nanoseconds_t default_latency, + bool is_receiver); }; //! Latency-related metrics. diff --git a/src/internal_modules/roc_audio/latency_monitor.h b/src/internal_modules/roc_audio/latency_monitor.h index 974a00d63..f60c0dfb4 100644 --- a/src/internal_modules/roc_audio/latency_monitor.h +++ b/src/internal_modules/roc_audio/latency_monitor.h @@ -82,7 +82,7 @@ class LatencyMonitor : public IFrameReader, public core::NonCopyable<> { //! Read audio frame from a pipeline. //! @remarks //! Forwards frame from underlying reader as-is. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode read(Frame& frame, packet::stream_timestamp_t duration, FrameReadMode mode); //! Report playback timestamp of last frame returned by read. diff --git a/src/internal_modules/roc_audio/mixer.cpp b/src/internal_modules/roc_audio/mixer.cpp index bd0ae1871..c6c0531c2 100644 --- a/src/internal_modules/roc_audio/mixer.cpp +++ b/src/internal_modules/roc_audio/mixer.cpp @@ -60,7 +60,7 @@ bool Mixer::has_input(IFrameReader& reader) { return false; } -ROC_NODISCARD status::StatusCode Mixer::add_input(IFrameReader& reader) { +ROC_ATTR_NODISCARD status::StatusCode Mixer::add_input(IFrameReader& reader) { roc_panic_if(init_status_ != status::StatusOK); Input input; diff --git a/src/internal_modules/roc_audio/mixer.h b/src/internal_modules/roc_audio/mixer.h index e25319618..8e5692054 100644 --- a/src/internal_modules/roc_audio/mixer.h +++ b/src/internal_modules/roc_audio/mixer.h @@ -63,7 +63,7 @@ class Mixer : public IFrameReader, public core::NonCopyable<> { bool has_input(IFrameReader& reader); //! Add input reader. - ROC_NODISCARD status::StatusCode add_input(IFrameReader& reader); + ROC_ATTR_NODISCARD status::StatusCode add_input(IFrameReader& reader); //! Remove input reader. void remove_input(IFrameReader& reader); @@ -75,7 +75,7 @@ class Mixer : public IFrameReader, public core::NonCopyable<> { //! @note //! Requested @p duration is allowed to be larger than maximum buffer //! size, but only if @p frame has pre-allocated buffer big enough. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode read(Frame& frame, packet::stream_timestamp_t duration, FrameReadMode mode); private: diff --git a/src/internal_modules/roc_audio/null_writer.h b/src/internal_modules/roc_audio/null_writer.h index 53db81b37..d716fc721 100644 --- a/src/internal_modules/roc_audio/null_writer.h +++ b/src/internal_modules/roc_audio/null_writer.h @@ -22,7 +22,7 @@ namespace audio { class NullWriter : public IFrameWriter, public core::NonCopyable<> { public: //! Write audio frame. - virtual ROC_NODISCARD status::StatusCode write(Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(Frame& frame); }; } // namespace audio diff --git a/src/internal_modules/roc_audio/packetizer.cpp b/src/internal_modules/roc_audio/packetizer.cpp index 365462643..82618b85f 100644 --- a/src/internal_modules/roc_audio/packetizer.cpp +++ b/src/internal_modules/roc_audio/packetizer.cpp @@ -161,17 +161,12 @@ status::StatusCode Packetizer::end_packet_() { // Fill protocol-specific fields. sequencer_.next(*packet_, packet_cts_, (packet::stream_timestamp_t)packet_pos_); - status::StatusCode code = status::StatusOK; // Apply padding if needed. if (packet_pos_ < samples_per_packet_) { - code = pad_packet_(written_payload_size); + pad_packet_(written_payload_size); } - if (code != status::StatusOK) { - return code; - } - - code = writer_.write(packet_); + const status::StatusCode code = writer_.write(packet_); if (code != status::StatusOK) { return code; } @@ -201,10 +196,9 @@ status::StatusCode Packetizer::create_packet_() { return status::StatusNoMem; } - status::StatusCode status = composer_.prepare(*pp, buffer, payload_size_); - if (status != status::StatusOK) { + if (!composer_.prepare(*pp, buffer, payload_size_)) { roc_log(LogError, "packetizer: can't prepare packet"); - return status; + return status::StatusNoMem; } pp->add_flags(packet::Packet::FlagPrepared); @@ -214,18 +208,15 @@ status::StatusCode Packetizer::create_packet_() { return status::StatusOK; } -status::StatusCode Packetizer::pad_packet_(size_t written_payload_size) { +void Packetizer::pad_packet_(size_t written_payload_size) { if (written_payload_size == payload_size_) { - return status::StatusOK; + return; } - status::StatusCode status = - composer_.pad(*packet_, payload_size_ - written_payload_size); - if (status != status::StatusOK) { - roc_log(LogError, "packetizer: can't pad packet: orig_size=%lu actual_size=%lu", - (unsigned long)payload_size_, (unsigned long)written_payload_size); + if (!composer_.pad(*packet_, payload_size_ - written_payload_size)) { + roc_panic("packetizer: can't pad packet: orig_size=%lu actual_size=%lu", + (unsigned long)payload_size_, (unsigned long)written_payload_size); } - return status; } } // namespace audio diff --git a/src/internal_modules/roc_audio/packetizer.h b/src/internal_modules/roc_audio/packetizer.h index 90fe24e07..e718c2a79 100644 --- a/src/internal_modules/roc_audio/packetizer.h +++ b/src/internal_modules/roc_audio/packetizer.h @@ -68,19 +68,19 @@ class Packetizer : public IFrameWriter, public core::NonCopyable<> { const PacketizerMetrics& metrics() const; //! Write audio frame. - virtual ROC_NODISCARD status::StatusCode write(Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(Frame& frame); //! Flush buffered packet, if any. //! @remarks //! Packet is padded to match fixed size. - ROC_NODISCARD status::StatusCode flush(); + ROC_ATTR_NODISCARD status::StatusCode flush(); private: status::StatusCode begin_packet_(); status::StatusCode end_packet_(); status::StatusCode create_packet_(); - status::StatusCode pad_packet_(size_t written_payload_size); + void pad_packet_(size_t written_payload_size); packet::IWriter& writer_; packet::IComposer& composer_; diff --git a/src/internal_modules/roc_audio/pcm_mapper_reader.h b/src/internal_modules/roc_audio/pcm_mapper_reader.h index ce10b4e43..2f36eed69 100644 --- a/src/internal_modules/roc_audio/pcm_mapper_reader.h +++ b/src/internal_modules/roc_audio/pcm_mapper_reader.h @@ -40,7 +40,7 @@ class PcmMapperReader : public IFrameReader, public core::NonCopyable<> { status::StatusCode init_status() const; //! Read audio frame. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode read(Frame& frame, packet::stream_timestamp_t duration, FrameReadMode mode); private: diff --git a/src/internal_modules/roc_audio/pcm_mapper_writer.h b/src/internal_modules/roc_audio/pcm_mapper_writer.h index 1225f7762..0323a276f 100644 --- a/src/internal_modules/roc_audio/pcm_mapper_writer.h +++ b/src/internal_modules/roc_audio/pcm_mapper_writer.h @@ -40,7 +40,7 @@ class PcmMapperWriter : public IFrameWriter, public core::NonCopyable<> { status::StatusCode init_status() const; //! Write audio frame. - virtual ROC_NODISCARD status::StatusCode write(Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(Frame& frame); private: FrameFactory& frame_factory_; diff --git a/src/internal_modules/roc_audio/pcm_subformat.cpp b/src/internal_modules/roc_audio/pcm_subformat.cpp index bf5537858..2d5f6840e 100644 --- a/src/internal_modules/roc_audio/pcm_subformat.cpp +++ b/src/internal_modules/roc_audio/pcm_subformat.cpp @@ -2159,13 +2159,13 @@ template struct pcm_sample; template <> struct pcm_sample { union { int8_t value; - ROC_PACKED_BEGIN struct { + ROC_ATTR_PACKED_BEGIN struct { #if ROC_CPU_ENDIAN == ROC_CPU_BE uint8_t octet0; #else uint8_t octet0; #endif - } ROC_PACKED_END octets; + } ROC_ATTR_PACKED_END octets; }; }; @@ -2173,13 +2173,13 @@ template <> struct pcm_sample { template <> struct pcm_sample { union { uint8_t value; - ROC_PACKED_BEGIN struct { + ROC_ATTR_PACKED_BEGIN struct { #if ROC_CPU_ENDIAN == ROC_CPU_BE uint8_t octet0; #else uint8_t octet0; #endif - } ROC_PACKED_END octets; + } ROC_ATTR_PACKED_END octets; }; }; @@ -2187,7 +2187,7 @@ template <> struct pcm_sample { template <> struct pcm_sample { union { int16_t value; - ROC_PACKED_BEGIN struct { + ROC_ATTR_PACKED_BEGIN struct { #if ROC_CPU_ENDIAN == ROC_CPU_BE uint8_t octet1; uint8_t octet0; @@ -2195,7 +2195,7 @@ template <> struct pcm_sample { uint8_t octet0; uint8_t octet1; #endif - } ROC_PACKED_END octets; + } ROC_ATTR_PACKED_END octets; }; }; @@ -2203,7 +2203,7 @@ template <> struct pcm_sample { template <> struct pcm_sample { union { uint16_t value; - ROC_PACKED_BEGIN struct { + ROC_ATTR_PACKED_BEGIN struct { #if ROC_CPU_ENDIAN == ROC_CPU_BE uint8_t octet1; uint8_t octet0; @@ -2211,7 +2211,7 @@ template <> struct pcm_sample { uint8_t octet0; uint8_t octet1; #endif - } ROC_PACKED_END octets; + } ROC_ATTR_PACKED_END octets; }; }; @@ -2219,7 +2219,7 @@ template <> struct pcm_sample { template <> struct pcm_sample { union { int32_t value; - ROC_PACKED_BEGIN struct { + ROC_ATTR_PACKED_BEGIN struct { #if ROC_CPU_ENDIAN == ROC_CPU_BE uint8_t octet3; uint8_t octet2; @@ -2231,7 +2231,7 @@ template <> struct pcm_sample { uint8_t octet2; uint8_t octet3; #endif - } ROC_PACKED_END octets; + } ROC_ATTR_PACKED_END octets; }; }; @@ -2239,7 +2239,7 @@ template <> struct pcm_sample { template <> struct pcm_sample { union { uint32_t value; - ROC_PACKED_BEGIN struct { + ROC_ATTR_PACKED_BEGIN struct { #if ROC_CPU_ENDIAN == ROC_CPU_BE uint8_t octet3; uint8_t octet2; @@ -2251,7 +2251,7 @@ template <> struct pcm_sample { uint8_t octet2; uint8_t octet3; #endif - } ROC_PACKED_END octets; + } ROC_ATTR_PACKED_END octets; }; }; @@ -2259,7 +2259,7 @@ template <> struct pcm_sample { template <> struct pcm_sample { union { int64_t value; - ROC_PACKED_BEGIN struct { + ROC_ATTR_PACKED_BEGIN struct { #if ROC_CPU_ENDIAN == ROC_CPU_BE uint8_t octet7; uint8_t octet6; @@ -2279,7 +2279,7 @@ template <> struct pcm_sample { uint8_t octet6; uint8_t octet7; #endif - } ROC_PACKED_END octets; + } ROC_ATTR_PACKED_END octets; }; }; @@ -2287,7 +2287,7 @@ template <> struct pcm_sample { template <> struct pcm_sample { union { uint64_t value; - ROC_PACKED_BEGIN struct { + ROC_ATTR_PACKED_BEGIN struct { #if ROC_CPU_ENDIAN == ROC_CPU_BE uint8_t octet7; uint8_t octet6; @@ -2307,7 +2307,7 @@ template <> struct pcm_sample { uint8_t octet6; uint8_t octet7; #endif - } ROC_PACKED_END octets; + } ROC_ATTR_PACKED_END octets; }; }; @@ -2315,7 +2315,7 @@ template <> struct pcm_sample { template <> struct pcm_sample { union { float value; - ROC_PACKED_BEGIN struct { + ROC_ATTR_PACKED_BEGIN struct { #if ROC_CPU_ENDIAN == ROC_CPU_BE uint8_t octet3; uint8_t octet2; @@ -2327,7 +2327,7 @@ template <> struct pcm_sample { uint8_t octet2; uint8_t octet3; #endif - } ROC_PACKED_END octets; + } ROC_ATTR_PACKED_END octets; }; }; @@ -2335,7 +2335,7 @@ template <> struct pcm_sample { template <> struct pcm_sample { union { double value; - ROC_PACKED_BEGIN struct { + ROC_ATTR_PACKED_BEGIN struct { #if ROC_CPU_ENDIAN == ROC_CPU_BE uint8_t octet7; uint8_t octet6; @@ -2355,7 +2355,7 @@ template <> struct pcm_sample { uint8_t octet6; uint8_t octet7; #endif - } ROC_PACKED_END octets; + } ROC_ATTR_PACKED_END octets; }; }; diff --git a/src/internal_modules/roc_audio/pcm_subformat_gen.py b/src/internal_modules/roc_audio/pcm_subformat_gen.py index 66953ade2..746462e8e 100755 --- a/src/internal_modules/roc_audio/pcm_subformat_gen.py +++ b/src/internal_modules/roc_audio/pcm_subformat_gen.py @@ -718,7 +718,7 @@ def nth_chars(codes, prefix=()): template <> struct pcm_sample<{{ type }}> { union { {{ type }} value; - ROC_PACKED_BEGIN struct { + ROC_ATTR_PACKED_BEGIN struct { #if ROC_CPU_ENDIAN == ROC_CPU_BE {% for n in reversed(range(size)) %} uint8_t octet{{ n }}; @@ -728,7 +728,7 @@ def nth_chars(codes, prefix=()): uint8_t octet{{ n }}; {% endfor %} #endif - } ROC_PACKED_END octets; + } ROC_ATTR_PACKED_END octets; }; }; diff --git a/src/internal_modules/roc_audio/plc_config.h b/src/internal_modules/roc_audio/plc_config.h index 761a76d55..2b5a8a5ba 100644 --- a/src/internal_modules/roc_audio/plc_config.h +++ b/src/internal_modules/roc_audio/plc_config.h @@ -44,7 +44,7 @@ struct PlcConfig { } //! Automatically fill missing settings. - ROC_NODISCARD bool deduce_defaults(); + ROC_ATTR_NODISCARD bool deduce_defaults(); }; //! Get string name of PLC backend. diff --git a/src/internal_modules/roc_audio/plc_reader.h b/src/internal_modules/roc_audio/plc_reader.h index 61fe7611e..1e798f383 100644 --- a/src/internal_modules/roc_audio/plc_reader.h +++ b/src/internal_modules/roc_audio/plc_reader.h @@ -56,7 +56,7 @@ class PlcReader : public IFrameReader, public core::NonCopyable<> { status::StatusCode init_status() const; //! Read audio frame. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode read(Frame& frame, packet::stream_timestamp_t duration, FrameReadMode mode); private: diff --git a/src/internal_modules/roc_audio/processor_map.h b/src/internal_modules/roc_audio/processor_map.h index 7dca9438c..b63e7202e 100644 --- a/src/internal_modules/roc_audio/processor_map.h +++ b/src/internal_modules/roc_audio/processor_map.h @@ -68,7 +68,7 @@ class ProcessorMap : public core::NonCopyable<> { void* backend_owner); //! Register custom PLC backend. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode register_plc(int backend_id, void* backend_owner, PlcFunc ctor_fn); //! Check if given backend is supported. diff --git a/src/internal_modules/roc_audio/profiling_reader.h b/src/internal_modules/roc_audio/profiling_reader.h index 95b65fdae..c9bdbaa64 100644 --- a/src/internal_modules/roc_audio/profiling_reader.h +++ b/src/internal_modules/roc_audio/profiling_reader.h @@ -35,7 +35,7 @@ class ProfilingReader : public IFrameReader, public core::NonCopyable<> { status::StatusCode init_status() const; //! Read audio frame. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode read(Frame& frame, packet::stream_timestamp_t duration, FrameReadMode mode); private: diff --git a/src/internal_modules/roc_audio/profiling_writer.h b/src/internal_modules/roc_audio/profiling_writer.h index 999ab4783..d4085970c 100644 --- a/src/internal_modules/roc_audio/profiling_writer.h +++ b/src/internal_modules/roc_audio/profiling_writer.h @@ -35,7 +35,7 @@ class ProfilingWriter : public IFrameWriter, public core::NonCopyable<> { status::StatusCode init_status() const; //! Write audio frame. - virtual ROC_NODISCARD status::StatusCode write(Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(Frame& frame); private: Profiler profiler_; diff --git a/src/internal_modules/roc_audio/resampler_config.h b/src/internal_modules/roc_audio/resampler_config.h index 48f39116a..05efc5714 100644 --- a/src/internal_modules/roc_audio/resampler_config.h +++ b/src/internal_modules/roc_audio/resampler_config.h @@ -68,9 +68,9 @@ struct ResamplerConfig { } //! Automatically fill missing settings. - ROC_NODISCARD bool deduce_defaults(class ProcessorMap& processor_map, - LatencyTunerBackend latency_backend, - LatencyTunerProfile latency_profile); + ROC_ATTR_NODISCARD bool deduce_defaults(class ProcessorMap& processor_map, + LatencyTunerBackend latency_backend, + LatencyTunerProfile latency_profile); }; //! Get string name of resampler backend. diff --git a/src/internal_modules/roc_audio/resampler_reader.h b/src/internal_modules/roc_audio/resampler_reader.h index 995513ff1..7403e4be3 100644 --- a/src/internal_modules/roc_audio/resampler_reader.h +++ b/src/internal_modules/roc_audio/resampler_reader.h @@ -44,7 +44,7 @@ class ResamplerReader : public IFrameReader, public core::NonCopyable<> { bool set_scaling(float multiplier); //! Read audio frame. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode read(Frame& frame, packet::stream_timestamp_t duration, FrameReadMode mode); private: diff --git a/src/internal_modules/roc_audio/resampler_writer.h b/src/internal_modules/roc_audio/resampler_writer.h index f0e4a77fa..8d75e1dc7 100644 --- a/src/internal_modules/roc_audio/resampler_writer.h +++ b/src/internal_modules/roc_audio/resampler_writer.h @@ -44,7 +44,7 @@ class ResamplerWriter : public IFrameWriter, public core::NonCopyable<> { bool set_scaling(float multiplier); //! Write audio frame. - virtual ROC_NODISCARD status::StatusCode write(Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(Frame& frame); private: status::StatusCode write_output_(const Frame& in_frame, size_t in_frame_pos); diff --git a/src/internal_modules/roc_audio/sample_spec.h b/src/internal_modules/roc_audio/sample_spec.h index 24ddeebd9..405ae3352 100644 --- a/src/internal_modules/roc_audio/sample_spec.h +++ b/src/internal_modules/roc_audio/sample_spec.h @@ -117,7 +117,7 @@ class SampleSpec { //! string format name to the file I/O library. //! @returns //! false if name is too long. - ROC_NODISCARD bool set_custom_format(const char* name); + ROC_ATTR_NODISCARD bool set_custom_format(const char* name); //! True if sub-format is set. bool has_subformat() const; @@ -148,7 +148,7 @@ class SampleSpec { //! See comment for set_custom_format() for rationale. //! @returns //! false if name is too long. - ROC_NODISCARD bool set_custom_subformat(const char* name); + ROC_ATTR_NODISCARD bool set_custom_subformat(const char* name); //! True if rate is set to non-zero value. bool has_sample_rate() const; @@ -359,7 +359,7 @@ class SampleSpec { //! //! @returns //! false if string can't be parsed. -ROC_NODISCARD bool parse_sample_spec(const char* str, SampleSpec& result); +ROC_ATTR_NODISCARD bool parse_sample_spec(const char* str, SampleSpec& result); //! Format sample spec to string. void format_sample_spec(const SampleSpec& sample_spec, core::StringBuilder& bld); diff --git a/src/internal_modules/roc_audio/watchdog.h b/src/internal_modules/roc_audio/watchdog.h index a669ad3b2..1b79bfa6c 100644 --- a/src/internal_modules/roc_audio/watchdog.h +++ b/src/internal_modules/roc_audio/watchdog.h @@ -85,8 +85,8 @@ struct WatchdogConfig { } //! Automatically fill missing settings. - ROC_NODISCARD bool deduce_defaults(const core::nanoseconds_t default_latency, - const core::nanoseconds_t target_latency); + ROC_ATTR_NODISCARD bool deduce_defaults(const core::nanoseconds_t default_latency, + const core::nanoseconds_t target_latency); }; //! Watchdog. @@ -106,7 +106,7 @@ class Watchdog : public IFrameReader, public core::NonCopyable<> { //! Read audio frame. //! @remarks //! Updates stream state and reads frame from the input reader. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode read(Frame& frame, packet::stream_timestamp_t duration, FrameReadMode mode); private: diff --git a/src/internal_modules/roc_core/array.h b/src/internal_modules/roc_core/array.h index ad5157ec9..9f82bc624 100644 --- a/src/internal_modules/roc_core/array.h +++ b/src/internal_modules/roc_core/array.h @@ -151,7 +151,7 @@ template class Array : public NonCopyable //! false if the allocation failed. //! @note //! has amortized O(1) complexity, O(n) in worst case. - ROC_NODISCARD bool push_back(const T& value) { + ROC_ATTR_NODISCARD bool push_back(const T& value) { if (!grow_exp(size_ + 1)) { return false; } @@ -180,7 +180,7 @@ template class Array : public NonCopyable //! Calls grow() to ensure that there is enough space in array. //! @returns //! false if the allocation failed - ROC_NODISCARD bool resize(size_t new_size) { + ROC_ATTR_NODISCARD bool resize(size_t new_size) { // Move objects to a new memory region if necessary. if (!grow(new_size)) { return false; @@ -214,7 +214,7 @@ template class Array : public NonCopyable //! region is allocated and the array elements are copied there. //! @returns //! false if the allocation failed. - ROC_NODISCARD bool grow(size_t min_capacity) { + ROC_ATTR_NODISCARD bool grow(size_t min_capacity) { if (min_capacity <= capacity_) { return true; } @@ -255,7 +255,7 @@ template class Array : public NonCopyable //! it reaches some threshold, and then starts growing linearly. //! @returns //! false if the allocation failed. - ROC_NODISCARD bool grow_exp(size_t min_capacity) { + ROC_ATTR_NODISCARD bool grow_exp(size_t min_capacity) { if (min_capacity <= capacity_) { return true; } diff --git a/src/internal_modules/roc_core/attributes.h b/src/internal_modules/roc_core/attributes.h index 9ddee19dc..6bc55817e 100644 --- a/src/internal_modules/roc_core/attributes.h +++ b/src/internal_modules/roc_core/attributes.h @@ -14,56 +14,64 @@ #include -//! Set "default" visibility for symbol. -//! Without this, "hidden" visibility is used for symbols. -#define ROC_EXPORT HEDLEY_PUBLIC +//! Explicitly specify a default visibility for a specific symbol. +#define ROC_ATTR_EXPORT HEDLEY_PUBLIC -#if HEDLEY_HAS_ATTRIBUTE(aligned) -//! Align structure field. -#define ROC_ALIGNED(x) __attribute__((aligned(x))) -#endif - -#if HEDLEY_HAS_ATTRIBUTE(packed) || HEDLEY_GCC_VERSION -//! Pack structure fields. -//! Place these before class or struct keyword. -#define ROC_PACKED_BEGIN -//! Pack structure fields. -//! Place these between '}' and ';'. -#define ROC_PACKED_END __attribute__((packed)) -#endif - -//! Hint for compiler that function takes printf-like arguments. -//! Compiler will emit warnings on mis-use. -#define ROC_PRINTF(fmt_pos, args_pos) HEDLEY_PRINTF_FORMAT(fmt_pos, args_pos) +//! Declares that the return operator is not reachable. +#define ROC_ATTR_UNREACHABLE_RETURN HEDLEY_UNREACHABLE_RETURN -//! Hint for compiler that function never returns. -#define ROC_NORETURN HEDLEY_NO_RETURN +//! Function never returns. +#define ROC_ATTR_NORETURN HEDLEY_NO_RETURN #ifdef HEDLEY_GCC_VERSION //! Emit warning if function result is not checked. -#define ROC_NODISCARD // GCC is too aggressive with this attribute. +#define ROC_ATTR_NODISCARD // GCC is too aggressive for this attribute. #else //! Emit warning if function result is not checked. -#define ROC_NODISCARD HEDLEY_WARN_UNUSED_RESULT +#define ROC_ATTR_NODISCARD HEDLEY_WARN_UNUSED_RESULT #endif +//! Function gets printf-like arguments. +#define ROC_ATTR_PRINTF(fmt_pos, args_pos) HEDLEY_PRINTF_FORMAT(fmt_pos, args_pos) + #if HEDLEY_HAS_ATTRIBUTE(unused) -//! Don't emit warning if function or variable is never used. -#define ROC_NOUNUSED __attribute__((unused)) +//! Function or variable is never used but no warning should be generated. +#define ROC_ATTR_UNUSED __attribute__((unused)) +#else +//! Function or variable is never used but no warning should be generated. +#define ROC_ATTR_UNUSED +#endif + +#if HEDLEY_HAS_ATTRIBUTE(packed) +//! Pack structure fields. +//! Place these before class or struct keyword. +#define ROC_ATTR_PACKED_BEGIN +//! Pack structure fields. +//! Place these between '}' and ';'. +#define ROC_ATTR_PACKED_END __attribute__((packed)) #else -//! Don't emit warning if function or variable is never used. -#define ROC_NOUNUSED +//! Pack structure fields. +//! Place these before class or struct keyword. +#define ROC_ATTR_PACKED_BEGIN +//! Pack structure fields. +//! Place these between '}' and ';'. +#define ROC_ATTR_PACKED_END +#endif + +#if HEDLEY_HAS_ATTRIBUTE(aligned) +//! The filed should have given alignment. +#define ROC_ATTR_ALIGNED(x) __attribute__((aligned(x))) #endif #if HEDLEY_HAS_ATTRIBUTE(no_sanitize) -//! Suppress sanitizers for a particular function. -#define ROC_NOSANITIZE __attribute__((no_sanitize("undefined"))) +//! Suppress undefined behavior sanitizer for a particular function. +#define ROC_ATTR_NO_SANITIZE_UB __attribute__((no_sanitize("undefined"))) #elif HEDLEY_HAS_ATTRIBUTE(no_sanitize_undefined) -//! Suppress sanitizers for a particular function. -#define ROC_NOSANITIZE __attribute__((no_sanitize_undefined)) +//! Suppress undefined behavior sanitizer for a particular function. +#define ROC_ATTR_NO_SANITIZE_UB __attribute__((no_sanitize_undefined)) #else -//! Suppress sanitizers for a particular function. -#define ROC_NOSANITIZE +//! Suppress undefined behavior sanitizer for a particular function. +#define ROC_ATTR_NO_SANITIZE_UB #endif #endif // ROC_CORE_ATTRIBUTES_H_ diff --git a/src/internal_modules/roc_core/hashmap.h b/src/internal_modules/roc_core/hashmap.h index 1a916d043..75b237f46 100644 --- a/src/internal_modules/roc_core/hashmap.h +++ b/src/internal_modules/roc_core/hashmap.h @@ -240,7 +240,7 @@ class Hashmap : public NonCopyable<> { //! Insertion speed is higher when insert to remove ratio is close to one or lower, //! and slows down when it becomes higher than one. The slow down is caused by //! the incremental rehashing algorithm. - ROC_NODISCARD bool insert(T& elem) { + ROC_ATTR_NODISCARD bool insert(T& elem) { HashmapData* data = to_node_data_(elem); if (!insert_(elem.key(), data)) { return false; @@ -284,7 +284,7 @@ class Hashmap : public NonCopyable<> { //! - doesn't computes key hashes //! - makes allocations and deallocations //! - doesn't proceed lazy rehashing - ROC_NODISCARD bool grow() { + ROC_ATTR_NODISCARD bool grow() { return impl_.grow(); } diff --git a/src/internal_modules/roc_core/hashmap_impl.h b/src/internal_modules/roc_core/hashmap_impl.h index 48aaf5eea..fa97adb81 100644 --- a/src/internal_modules/roc_core/hashmap_impl.h +++ b/src/internal_modules/roc_core/hashmap_impl.h @@ -86,7 +86,7 @@ class HashmapImpl { void remove(HashmapData* node, bool skip_rehash); //! Grow hashtable capacity. - ROC_NODISCARD bool grow(); + ROC_ATTR_NODISCARD bool grow(); private: HashmapData* find_in_bucket_(const Bucket& bucket, diff --git a/src/internal_modules/roc_core/ipool.h b/src/internal_modules/roc_core/ipool.h index 67c2b3b2f..74799d5fd 100644 --- a/src/internal_modules/roc_core/ipool.h +++ b/src/internal_modules/roc_core/ipool.h @@ -34,7 +34,7 @@ class IPool { //! Reserve memory for given number of objects. //! @returns //! false if allocation failed. - virtual ROC_NODISCARD bool reserve(size_t n_objects) = 0; + virtual ROC_ATTR_NODISCARD bool reserve(size_t n_objects) = 0; //! Allocate memory for an object. //! @returns diff --git a/src/internal_modules/roc_core/limited_pool.cpp b/src/internal_modules/roc_core/limited_pool.cpp index af7dd7242..d35e6c267 100644 --- a/src/internal_modules/roc_core/limited_pool.cpp +++ b/src/internal_modules/roc_core/limited_pool.cpp @@ -24,7 +24,7 @@ size_t LimitedPool::object_size() const { return pool_.object_size(); } -ROC_NODISCARD bool LimitedPool::reserve(size_t n_objects) { +ROC_ATTR_NODISCARD bool LimitedPool::reserve(size_t n_objects) { return pool_.reserve(n_objects); } diff --git a/src/internal_modules/roc_core/limited_pool.h b/src/internal_modules/roc_core/limited_pool.h index cca34f925..97a56d62c 100644 --- a/src/internal_modules/roc_core/limited_pool.h +++ b/src/internal_modules/roc_core/limited_pool.h @@ -34,7 +34,7 @@ class LimitedPool : public NonCopyable, public IPool { //! Reserve memory for given number of objects. //! @returns //! false if allocation failed. - virtual ROC_NODISCARD bool reserve(size_t n_objects); + virtual ROC_ATTR_NODISCARD bool reserve(size_t n_objects); //! Allocate memory for an object, after checking with the memory limiter. //! @returns diff --git a/src/internal_modules/roc_core/log.h b/src/internal_modules/roc_core/log.h index c8ad73b7e..7565254ae 100644 --- a/src/internal_modules/roc_core/log.h +++ b/src/internal_modules/roc_core/log.h @@ -107,7 +107,7 @@ class Logger : public NonCopyable<> { } //! Print message to log. - ROC_PRINTF(6, 7) + ROC_ATTR_PRINTF(6, 7) void writef(LogLevel level, const char* module, const char* file, diff --git a/src/internal_modules/roc_core/memory_limiter.h b/src/internal_modules/roc_core/memory_limiter.h index 0a5be492a..bf00ff7ac 100644 --- a/src/internal_modules/roc_core/memory_limiter.h +++ b/src/internal_modules/roc_core/memory_limiter.h @@ -38,7 +38,7 @@ class MemoryLimiter : public NonCopyable<> { //! Track acquired memory. //! @returns //! true if successful i.e. maximum limit not breached. - ROC_NODISCARD bool acquire(size_t num_bytes); + ROC_ATTR_NODISCARD bool acquire(size_t num_bytes); //! Track released memory. //! This will panic if we are releasing more than what is currently acquired. diff --git a/src/internal_modules/roc_core/panic.h b/src/internal_modules/roc_core/panic.h index db9f69237..ad770f7df 100644 --- a/src/internal_modules/roc_core/panic.h +++ b/src/internal_modules/roc_core/panic.h @@ -54,7 +54,7 @@ namespace roc { namespace core { //! Print error message and terminate program gracefully. -ROC_NORETURN ROC_PRINTF(4, 5) void panic( +ROC_ATTR_NORETURN ROC_ATTR_PRINTF(4, 5) void panic( const char* module, const char* file, int line, const char* format, ...); } // namespace core diff --git a/src/internal_modules/roc_core/parse_units.h b/src/internal_modules/roc_core/parse_units.h index 59cf67044..9e7052e0d 100644 --- a/src/internal_modules/roc_core/parse_units.h +++ b/src/internal_modules/roc_core/parse_units.h @@ -31,7 +31,7 @@ namespace core { //! //! @returns //! false if string can't be parsed. -ROC_NODISCARD bool parse_duration(const char* string, nanoseconds_t& result); +ROC_ATTR_NODISCARD bool parse_duration(const char* string, nanoseconds_t& result); //! Parse size from string. //! @@ -44,7 +44,7 @@ ROC_NODISCARD bool parse_duration(const char* string, nanoseconds_t& result); //! //! @returns //! false if string can't be parsed. -ROC_NODISCARD bool parse_size(const char* string, size_t& result); +ROC_ATTR_NODISCARD bool parse_size(const char* string, size_t& result); } // namespace core } // namespace roc diff --git a/src/internal_modules/roc_core/printer.h b/src/internal_modules/roc_core/printer.h index e564a4849..add558d5c 100644 --- a/src/internal_modules/roc_core/printer.h +++ b/src/internal_modules/roc_core/printer.h @@ -38,7 +38,7 @@ class Printer : public NonCopyable<> { //! Write text. //! @returns size of formatted string (excluding terminating zero byte). - ROC_PRINTF(2, 3) size_t writef(const char* format, ...); + ROC_ATTR_PRINTF(2, 3) size_t writef(const char* format, ...); private: void flush_(bool force); diff --git a/src/internal_modules/roc_core/ring_queue.h b/src/internal_modules/roc_core/ring_queue.h index 9a64d8d2c..b131c4846 100644 --- a/src/internal_modules/roc_core/ring_queue.h +++ b/src/internal_modules/roc_core/ring_queue.h @@ -178,7 +178,7 @@ template class RingQueue : public NonCopy //! the end of the queue. //! @returns //! false if the allocation failed - ROC_NODISCARD bool resize(size_t new_capacity) { + ROC_ATTR_NODISCARD bool resize(size_t new_capacity) { const size_t old_capacity = capacity(); if (new_capacity == old_capacity) { return true; diff --git a/src/internal_modules/roc_core/secure_random.h b/src/internal_modules/roc_core/secure_random.h deleted file mode 100644 index 412b6e195..000000000 --- a/src/internal_modules/roc_core/secure_random.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2025 Roc Streaming authors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -//! @file roc_core/secure_random.h -//! @brief Helpers to generate cryptographically secure random numbers. - -#ifndef ROC_CORE_SECURE_RANDOM_H_ -#define ROC_CORE_SECURE_RANDOM_H_ - -#include "roc_core/attributes.h" -#include "roc_core/stddefs.h" - -//! @warning On some platforms CSPRNG is not available. In this case a non-secure version -//! may be used instead (e.g. @p fast_random*()). - -namespace roc { -namespace core { - -//! Fill buffer @p buf with @p bufsz random bites. -//! Thread-safe. Uniformly distributed. -//! -//! @returns @p true in case of success, @p false in case of failure. -ROC_NODISCARD -bool secure_random(void* buf, size_t bufsz); - -//! Get random 32-bit integer in range [@p from; @p to] and put it to @p dest. -//! Thread-safe. Uniformly distributed. -//! -//! @returns @p true in case of success, @p false in case of failure. -ROC_NODISCARD -bool secure_random_range_32(uint32_t from, uint32_t to, uint32_t& dest); - -//! Get random 64-bit integer in range [@p from; @p to] and put it to @p dest. -//! Thread-safe. Uniformly distributed. -//! -//! @returns @p true in case of success, @p false in case of failure. -ROC_NODISCARD -bool secure_random_range_64(uint64_t from, uint64_t to, uint64_t& dest); - -} // namespace core -} // namespace roc - -#endif // ROC_CORE_SECURE_RANDOM_H_ diff --git a/src/internal_modules/roc_core/slab_pool.h b/src/internal_modules/roc_core/slab_pool.h index fbcc3e748..e2cbb822c 100644 --- a/src/internal_modules/roc_core/slab_pool.h +++ b/src/internal_modules/roc_core/slab_pool.h @@ -107,7 +107,7 @@ class SlabPool : public IPool, public NonCopyable<> { } //! Reserve memory for given number of objects. - virtual ROC_NODISCARD bool reserve(size_t n_objects) { + virtual ROC_ATTR_NODISCARD bool reserve(size_t n_objects) { return impl_.reserve(n_objects); } diff --git a/src/internal_modules/roc_core/slab_pool_impl.h b/src/internal_modules/roc_core/slab_pool_impl.h index 4545c3cd0..8412b02e5 100644 --- a/src/internal_modules/roc_core/slab_pool_impl.h +++ b/src/internal_modules/roc_core/slab_pool_impl.h @@ -70,7 +70,7 @@ class SlabPoolImpl : public NonCopyable<> { ~SlabPoolImpl(); //! Reserve memory for given number of objects. - ROC_NODISCARD bool reserve(size_t n_objects); + ROC_ATTR_NODISCARD bool reserve(size_t n_objects); //! Allocate memory for an object. void* allocate(); diff --git a/src/internal_modules/roc_core/string_buffer.h b/src/internal_modules/roc_core/string_buffer.h index a3b2595a1..8aeb2eda9 100644 --- a/src/internal_modules/roc_core/string_buffer.h +++ b/src/internal_modules/roc_core/string_buffer.h @@ -48,13 +48,13 @@ class StringBuffer : public NonCopyable<> { //! @p str should be zero-terminated. //! @returns //! false if allocation failed. - ROC_NODISCARD bool assign(const char* str); + ROC_ATTR_NODISCARD bool assign(const char* str); //! Copy given range into buffer. //! Buffer will be automatically zero-terminated. //! @returns //! false if allocation failed. - ROC_NODISCARD bool assign(const char* str_begin, const char* str_end); + ROC_ATTR_NODISCARD bool assign(const char* str_begin, const char* str_end); //! Extend buffer by requested number of characters. //! @remarks @@ -62,19 +62,19 @@ class StringBuffer : public NonCopyable<> { //! It's the caller responsibility to fill them. //! @returns //! NULL if allocation failed. - ROC_NODISCARD char* extend(size_t n_chars); + ROC_ATTR_NODISCARD char* extend(size_t n_chars); //! Grow capacity to be able to hold desired number of characters. //! Capacity is increased linearly. //! @returns //! false if allocation failed. - ROC_NODISCARD bool grow(size_t desired_len); + ROC_ATTR_NODISCARD bool grow(size_t desired_len); //! Grow capacity to be able to hold desired number of characters. //! Capacity is increased exponentially. //! @returns //! false if allocation failed. - ROC_NODISCARD bool grow_exp(size_t desired_len); + ROC_ATTR_NODISCARD bool grow_exp(size_t desired_len); private: Array data_; diff --git a/src/internal_modules/roc_core/string_list.h b/src/internal_modules/roc_core/string_list.h index 311e58bce..768d269d2 100644 --- a/src/internal_modules/roc_core/string_list.h +++ b/src/internal_modules/roc_core/string_list.h @@ -79,19 +79,19 @@ class StringList : public NonCopyable<> { //! Reallocates memory if necessary. //! @returns //! false if allocation failed. - ROC_NODISCARD bool push_back(const char* str); + ROC_ATTR_NODISCARD bool push_back(const char* str); //! Append string from a range to the list. //! @remarks //! Reallocates memory if necessary. //! @returns //! false if allocation failed. - ROC_NODISCARD bool push_back(const char* str_begin, const char* str_end); + ROC_ATTR_NODISCARD bool push_back(const char* str_begin, const char* str_end); //! Remove string from end of the list. //! @returns //! false if deallocation failed. - ROC_NODISCARD bool pop_back(); + ROC_ATTR_NODISCARD bool pop_back(); //! Find string in the list. //! @returns diff --git a/src/internal_modules/roc_core/target_android/roc_core/console.h b/src/internal_modules/roc_core/target_android/roc_core/console.h index 5674b5be9..a414b8ec7 100644 --- a/src/internal_modules/roc_core/target_android/roc_core/console.h +++ b/src/internal_modules/roc_core/target_android/roc_core/console.h @@ -26,10 +26,10 @@ enum Color { bool console_supports_colors(); //! Print line. -ROC_PRINTF(1, 2) void console_println(const char* format, ...); +ROC_ATTR_PRINTF(1, 2) void console_println(const char* format, ...); //! Print line (with color). -ROC_PRINTF(2, 3) void console_println(Color color, const char* format, ...); +ROC_ATTR_PRINTF(2, 3) void console_println(Color color, const char* format, ...); } // namespace core } // namespace roc diff --git a/src/internal_modules/roc_core/target_darwin/roc_core/semaphore.h b/src/internal_modules/roc_core/target_darwin/roc_core/semaphore.h index 05f9dec47..c607120cc 100644 --- a/src/internal_modules/roc_core/target_darwin/roc_core/semaphore.h +++ b/src/internal_modules/roc_core/target_darwin/roc_core/semaphore.h @@ -32,7 +32,7 @@ class Semaphore : public NonCopyable<> { //! Wait until the counter becomes non-zero, decrement it, and return true. //! If deadline expires before the counter becomes non-zero, returns false. //! Deadline should be in the same time domain as core::timestamp(). - ROC_NODISCARD bool timed_wait(nanoseconds_t deadline); + ROC_ATTR_NODISCARD bool timed_wait(nanoseconds_t deadline); //! Wait until the counter becomes non-zero, decrement it, and return. void wait(); diff --git a/src/internal_modules/roc_core/target_libunwind/roc_core/backtrace.cpp b/src/internal_modules/roc_core/target_libunwind/roc_core/backtrace.cpp index e3994c69e..2c0df9670 100644 --- a/src/internal_modules/roc_core/target_libunwind/roc_core/backtrace.cpp +++ b/src/internal_modules/roc_core/target_libunwind/roc_core/backtrace.cpp @@ -10,8 +10,8 @@ #define UNW_LOCAL_ONLY // Workaround to support building with -std=c++98. -#ifdef ROC_ALIGNED -#define alignas(x) ROC_ALIGNED(x) +#ifdef ROC_ATTR_ALIGNED +#define alignas(x) ROC_ATTR_ALIGNED(x) #endif #include diff --git a/src/internal_modules/roc_core/target_libuuid/roc_core/uuid.cpp b/src/internal_modules/roc_core/target_libuuid/roc_core/uuid.cpp index cb2eee680..d0fa3d4da 100644 --- a/src/internal_modules/roc_core/target_libuuid/roc_core/uuid.cpp +++ b/src/internal_modules/roc_core/target_libuuid/roc_core/uuid.cpp @@ -15,7 +15,7 @@ namespace roc { namespace core { // Uses libuuid to generate the uuid. -bool uuid_generate(char* buf, size_t buf_sz) { +bool uuid_generare(char* buf, size_t buf_sz) { if (!buf) { roc_panic("uuid: buffer is null"); } diff --git a/src/internal_modules/roc_core/target_nocsprng/roc_core/secure_random.cpp b/src/internal_modules/roc_core/target_nocsprng/roc_core/secure_random.cpp deleted file mode 100644 index db290be46..000000000 --- a/src/internal_modules/roc_core/target_nocsprng/roc_core/secure_random.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2025 Roc Streaming authors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "roc_core/secure_random.h" -#include "roc_core/fast_random.h" - -namespace roc { -namespace core { - -bool secure_random(void* buf, size_t bufsz) { - unsigned char* ubuf = (unsigned char*)buf; - - size_t i = 0; - while (i < bufsz) { - union { - uint32_t number; - unsigned char bytes[4]; - } rand; - rand.number = fast_random_32(); - - // clang-format off - ubuf[i] = rand.bytes[0]; i++; if (i >= bufsz) { break; } - ubuf[i] = rand.bytes[1]; i++; if (i >= bufsz) { break; } - ubuf[i] = rand.bytes[2]; i++; if (i >= bufsz) { break; } - ubuf[i] = rand.bytes[3]; i++; - // clang-format on - } - return true; -} - -bool secure_random_range_32(uint32_t from, uint32_t to, uint32_t& dest) { - dest = (uint32_t)fast_random_range(from, to); - return true; -} - -bool secure_random_range_64(uint64_t from, uint64_t to, uint64_t& dest) { - dest = fast_random_range(from, to); - return true; -} - -} // namespace core -} // namespace roc diff --git a/src/internal_modules/roc_core/target_nouuid/roc_core/uuid.cpp b/src/internal_modules/roc_core/target_nouuid/roc_core/uuid.cpp index b4742fddb..144e22015 100644 --- a/src/internal_modules/roc_core/target_nouuid/roc_core/uuid.cpp +++ b/src/internal_modules/roc_core/target_nouuid/roc_core/uuid.cpp @@ -7,9 +7,9 @@ */ #include "roc_core/uuid.h" +#include "roc_core/fast_random.h" #include "roc_core/macro_helpers.h" #include "roc_core/panic.h" -#include "roc_core/secure_random.h" #include "roc_core/stddefs.h" namespace roc { @@ -26,7 +26,7 @@ namespace core { // // In text form, UUID is 36 characters long (32 hex chars + 4 dashes), // plus terminating zero bye. -bool uuid_generate(char* buf, size_t buf_sz) { +bool uuid_generare(char* buf, size_t buf_sz) { if (!buf) { roc_panic("uuid: buffer is null"); } @@ -35,9 +35,8 @@ bool uuid_generate(char* buf, size_t buf_sz) { } uint8_t bytes[16]; - bool ok = core::secure_random(bytes, ROC_ARRAY_SIZE(bytes)); - if (!ok) { - return false; + for (size_t i = 0; i < ROC_ARRAY_SIZE(bytes); i++) { + bytes[i] = (uint8_t)fast_random_range(0, 255); } // Set variant to OSF DCE UUID. diff --git a/src/internal_modules/roc_core/target_openssl/roc_core/secure_random.cpp b/src/internal_modules/roc_core/target_openssl/roc_core/secure_random.cpp deleted file mode 100644 index c97a1a121..000000000 --- a/src/internal_modules/roc_core/target_openssl/roc_core/secure_random.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2025 Roc Streaming authors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "roc_core/secure_random.h" -#include "roc_core/log.h" -#include "roc_core/macro_helpers.h" - -#include -#include - -namespace roc { -namespace core { - -bool secure_random(void* buf, size_t bufsz) { - // RAND_priv_bytes() is not needed right now as we do not use these random numbers - // privately. See also https://docs.openssl.org/3.0/man7/RAND/ - - int ok = RAND_bytes((unsigned char*)buf, (int)bufsz); - - if (ok != 1) { - unsigned long err; - char err_str[256]; // minimum buf length is 256 - memset(err_str, 0, ROC_ARRAY_SIZE(err_str)); - while ((err = ERR_get_error()) != 0) { - ERR_error_string_n(err, err_str, ROC_ARRAY_SIZE(err_str)); - roc_log(LogError, "secure random: OpenSSL RAND_bytes() failed: %s", err_str); - } - return false; - } - return true; -} - -bool secure_random_range_32(uint32_t from, uint32_t to, uint32_t& dest) { - // validation `to >= from` exists in the 64-bit version called below - - if (from == 0 && to == UINT32_MAX) { - return secure_random(&dest, sizeof(dest)); - } - - uint64_t rand64; - bool ok = secure_random_range_64(from, to, rand64); - if (!ok) { - return false; - } - dest = (uint32_t)rand64; - return true; -} - -bool secure_random_range_64(uint64_t from, uint64_t to, uint64_t& dest) { - // same as fast_random_range() except it calls CSPRNG to get a uint64 value - - roc_panic_if_msg(from > to, "secure random: invalid range: from=%llu to=%llu", - (unsigned long long)from, (unsigned long long)to); - - // corner case check; needed to avoid a possible uint64_t overflow - if (from == 0 && to == UINT64_MAX) { - return secure_random(&dest, sizeof(dest)); - } - - const uint64_t range = to - from + 1; - - // Generate a mask with 1's from bit 0 to the most significant bit in `range`. - // At each step, we double the count of leading 1's: - // 0001....... - // 00011...... - // 0001111.... - // Thanks to @rnovatorov for the hint. - uint64_t mask = range; - mask |= mask >> 1; - mask |= mask >> 2; - mask |= mask >> 4; - mask |= mask >> 8; - mask |= mask >> 16; - mask |= mask >> 32; - - do { - bool ok = secure_random(&dest, sizeof(dest)); - if (!ok) { - return false; - } - dest &= mask; - } while (dest >= range); - - dest += from; - - roc_panic_if_not(dest >= from); - roc_panic_if_not(dest <= to); - - return true; -} - -} // namespace core -} // namespace roc diff --git a/src/internal_modules/roc_core/target_posix/roc_core/cond.h b/src/internal_modules/roc_core/target_posix/roc_core/cond.h index 5d6ae3e33..9b33f3312 100644 --- a/src/internal_modules/roc_core/target_posix/roc_core/cond.h +++ b/src/internal_modules/roc_core/target_posix/roc_core/cond.h @@ -35,7 +35,7 @@ class Cond : public NonCopyable<> { //! Wait with timeout. //! @returns false if timeout expired. - ROC_NODISCARD bool timed_wait(nanoseconds_t timeout) const; + ROC_ATTR_NODISCARD bool timed_wait(nanoseconds_t timeout) const; //! Wait. void wait() const; diff --git a/src/internal_modules/roc_core/target_posix/roc_core/crash_handler.cpp b/src/internal_modules/roc_core/target_posix/roc_core/crash_handler.cpp index df51a5414..babbf8c14 100644 --- a/src/internal_modules/roc_core/target_posix/roc_core/crash_handler.cpp +++ b/src/internal_modules/roc_core/target_posix/roc_core/crash_handler.cpp @@ -65,7 +65,7 @@ const char* signal_string(int sig, siginfo_t* si) { return "caught unknown signal"; } -ROC_NORETURN void signal_handler(int sig, siginfo_t* si, void*) { +ROC_ATTR_NORETURN void signal_handler(int sig, siginfo_t* si, void*) { die_gracefully(signal_string(sig, si), false); } diff --git a/src/internal_modules/roc_core/target_posix/roc_core/die.h b/src/internal_modules/roc_core/target_posix/roc_core/die.h index e9a015d67..a374dc1a3 100644 --- a/src/internal_modules/roc_core/target_posix/roc_core/die.h +++ b/src/internal_modules/roc_core/target_posix/roc_core/die.h @@ -20,12 +20,12 @@ namespace core { //! Terminate program. //! @remarks //! Terminates immediately without calling destructors and exit handlers. -ROC_NORETURN void die_fast(int code); +ROC_ATTR_NORETURN void die_fast(int code); //! Terminate program with error message and backtrace. //! @remarks //! Prints error message, backtraces, and terminates program with error. -ROC_NORETURN void die_gracefully(const char* message, bool full_backtrace); +ROC_ATTR_NORETURN void die_gracefully(const char* message, bool full_backtrace); } // namespace core } // namespace roc diff --git a/src/internal_modules/roc_core/target_posix/roc_core/mutex.h b/src/internal_modules/roc_core/target_posix/roc_core/mutex.h index f606f1efe..bec88bde8 100644 --- a/src/internal_modules/roc_core/target_posix/roc_core/mutex.h +++ b/src/internal_modules/roc_core/target_posix/roc_core/mutex.h @@ -40,7 +40,7 @@ class Mutex : public NonCopyable<> { ~Mutex(); //! Try to lock the mutex. - ROC_NODISCARD inline bool try_lock() const { + ROC_ATTR_NODISCARD inline bool try_lock() const { const int err = pthread_mutex_trylock(&mutex_); if (err != 0 && err != EBUSY && err != EAGAIN) { diff --git a/src/internal_modules/roc_core/target_posix/roc_core/singleton.h b/src/internal_modules/roc_core/target_posix/roc_core/singleton.h index 02915918d..d22ef072c 100644 --- a/src/internal_modules/roc_core/target_posix/roc_core/singleton.h +++ b/src/internal_modules/roc_core/target_posix/roc_core/singleton.h @@ -49,11 +49,9 @@ template class Singleton : public NonCopyable<> { static T* instance_; }; -//! @cond HIDDEN template pthread_once_t Singleton::once_ = PTHREAD_ONCE_INIT; template AlignedStorage Singleton::storage_; template T* Singleton::instance_; -//! @endcond } // namespace core } // namespace roc diff --git a/src/internal_modules/roc_core/target_posix/roc_core/thread.h b/src/internal_modules/roc_core/target_posix/roc_core/thread.h index d7980bd49..43b2d0568 100644 --- a/src/internal_modules/roc_core/target_posix/roc_core/thread.h +++ b/src/internal_modules/roc_core/target_posix/roc_core/thread.h @@ -33,7 +33,7 @@ class Thread : public NonCopyable { static uint64_t get_tid(); //! Raise current thread priority to realtime. - ROC_NODISCARD static bool enable_realtime(); + ROC_ATTR_NODISCARD static bool enable_realtime(); //! Check if thread was started and can be joined. //! @returns @@ -43,7 +43,7 @@ class Thread : public NonCopyable { //! Start thread. //! @remarks //! Executes run() in new thread. - ROC_NODISCARD bool start(); + ROC_ATTR_NODISCARD bool start(); //! Join thread. //! @remarks diff --git a/src/internal_modules/roc_core/target_posix_ext/roc_core/semaphore.h b/src/internal_modules/roc_core/target_posix_ext/roc_core/semaphore.h index 6e594e4d7..7c9e71c4c 100644 --- a/src/internal_modules/roc_core/target_posix_ext/roc_core/semaphore.h +++ b/src/internal_modules/roc_core/target_posix_ext/roc_core/semaphore.h @@ -33,7 +33,7 @@ class Semaphore : public NonCopyable<> { //! Wait until the counter becomes non-zero, decrement it, and return true. //! If deadline expires before the counter becomes non-zero, returns false. //! Deadline should be in the same time domain as core::timestamp(). - ROC_NODISCARD bool timed_wait(nanoseconds_t deadline); + ROC_ATTR_NODISCARD bool timed_wait(nanoseconds_t deadline); //! Wait until the counter becomes non-zero, decrement it, and return. void wait(); diff --git a/src/internal_modules/roc_core/target_posix_pc/roc_core/console.h b/src/internal_modules/roc_core/target_posix_pc/roc_core/console.h index b9a1afa1c..8be627f0b 100644 --- a/src/internal_modules/roc_core/target_posix_pc/roc_core/console.h +++ b/src/internal_modules/roc_core/target_posix_pc/roc_core/console.h @@ -34,10 +34,10 @@ enum Color { bool console_supports_colors(); //! Print line. -ROC_PRINTF(1, 2) void console_println(const char* format, ...); +ROC_ATTR_PRINTF(1, 2) void console_println(const char* format, ...); //! Print line (with color). -ROC_PRINTF(2, 3) void console_println(Color color, const char* format, ...); +ROC_ATTR_PRINTF(2, 3) void console_println(Color color, const char* format, ...); } // namespace core } // namespace roc diff --git a/src/internal_modules/roc_core/uuid.h b/src/internal_modules/roc_core/uuid.h index b9367888a..ed9143797 100644 --- a/src/internal_modules/roc_core/uuid.h +++ b/src/internal_modules/roc_core/uuid.h @@ -26,7 +26,7 @@ enum { //! @note //! Generated string has UuidLen characters + null terminator. //! Panics if @p buf is null or @p buf_sz is less than UuidLen + 1. -bool uuid_generate(char* buf, size_t buf_sz); +bool uuid_generare(char* buf, size_t buf_sz); } // namespace core } // namespace roc diff --git a/src/internal_modules/roc_ctl/control_loop.h b/src/internal_modules/roc_ctl/control_loop.h index 8300621a1..d77f72431 100644 --- a/src/internal_modules/roc_ctl/control_loop.h +++ b/src/internal_modules/roc_ctl/control_loop.h @@ -198,7 +198,7 @@ class ControlLoop : public ControlTaskExecutor, public core::NonCop //! Combines schedule() and wait() calls. //! @returns //! true if the task succeeded or false if it failed. - ROC_NODISCARD bool schedule_and_wait(ControlTask& task); + ROC_ATTR_NODISCARD bool schedule_and_wait(ControlTask& task); //! Try to cancel scheduled task execution, if it's not executed yet. //! @see ControlTaskQueue::async_cancel for details. diff --git a/src/internal_modules/roc_dbgio/csv_dumper.h b/src/internal_modules/roc_dbgio/csv_dumper.h index 210fc6566..226dcabbb 100644 --- a/src/internal_modules/roc_dbgio/csv_dumper.h +++ b/src/internal_modules/roc_dbgio/csv_dumper.h @@ -74,7 +74,7 @@ class CsvDumper : private core::Thread { ~CsvDumper(); //! Open file and start background thread. - ROC_NODISCARD status::StatusCode open(); + ROC_ATTR_NODISCARD status::StatusCode open(); //! Stop background thread and close file. void close(); diff --git a/src/internal_modules/roc_dbgio/print_supported.h b/src/internal_modules/roc_dbgio/print_supported.h index fc8e5b878..42188b4a7 100644 --- a/src/internal_modules/roc_dbgio/print_supported.h +++ b/src/internal_modules/roc_dbgio/print_supported.h @@ -28,9 +28,9 @@ enum { }; //! Print supported protocols, formats, etc. -ROC_NODISCARD bool print_supported(unsigned flags, - sndio::BackendDispatcher& backend_dispatcher, - core::IArena& arena); +ROC_ATTR_NODISCARD bool print_supported(unsigned flags, + sndio::BackendDispatcher& backend_dispatcher, + core::IArena& arena); } // namespace dbgio } // namespace roc diff --git a/src/internal_modules/roc_fec/block_reader.cpp b/src/internal_modules/roc_fec/block_reader.cpp index 50d8aebe0..ae7ce19b3 100644 --- a/src/internal_modules/roc_fec/block_reader.cpp +++ b/src/internal_modules/roc_fec/block_reader.cpp @@ -314,10 +314,10 @@ status::StatusCode BlockReader::parse_repaired_packet_(const core::Sliceset_buffer(buffer); diff --git a/src/internal_modules/roc_fec/block_reader.h b/src/internal_modules/roc_fec/block_reader.h index 504174dc8..fa8b22541 100644 --- a/src/internal_modules/roc_fec/block_reader.h +++ b/src/internal_modules/roc_fec/block_reader.h @@ -72,8 +72,8 @@ class BlockReader : public packet::IReader, public core::NonCopyable<> { //! Read packet. //! @remarks //! When a packet loss is detected, try to restore it from repair packets. - virtual ROC_NODISCARD status::StatusCode read(packet::PacketPtr& packet, - packet::PacketReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode read(packet::PacketPtr& packet, + packet::PacketReadMode mode); private: status::StatusCode try_start_(); diff --git a/src/internal_modules/roc_fec/block_writer.cpp b/src/internal_modules/roc_fec/block_writer.cpp index 1cf4768cc..8f720e28f 100644 --- a/src/internal_modules/roc_fec/block_writer.cpp +++ b/src/internal_modules/roc_fec/block_writer.cpp @@ -7,11 +7,11 @@ */ #include "roc_fec/block_writer.h" +#include "roc_core/fast_random.h" #include "roc_core/log.h" #include "roc_core/panic.h" -#include "roc_core/secure_random.h" #include "roc_packet/fec_scheme.h" -#include "roc_status/status_code.h" +#include "roc_status/code_to_str.h" namespace roc { namespace fec { @@ -46,16 +46,9 @@ BlockWriter::BlockWriter(const BlockWriterConfig& config, return; } - bool ok = core::secure_random(&cur_sbn_, sizeof(cur_sbn_)); - if (!ok) { - init_status_ = status::StatusErrRand; - return; - } - ok = core::secure_random(&cur_block_repair_sn_, sizeof(cur_block_repair_sn_)); - if (!ok) { - init_status_ = status::StatusErrRand; - return; - } + cur_sbn_ = (packet::blknum_t)core::fast_random_range(0, packet::blknum_t(-1)); + cur_block_repair_sn_ = + (packet::seqnum_t)core::fast_random_range(0, packet::seqnum_t(-1)); if ((init_status_ = resize(config.n_source_packets, config.n_repair_packets)) != status::StatusOK) { @@ -230,10 +223,9 @@ status::StatusCode BlockWriter::write_source_packet_(const packet::PacketPtr& pp fill_packet_fec_fields_(pp, (packet::seqnum_t)cur_packet_); - status::StatusCode status = source_composer_.compose(*pp); - if (status != status::StatusOK) { - roc_log(LogError, "fec block writer: can't compose packet"); - return status; + if (!source_composer_.compose(*pp)) { + // TODO(gh-183): forward status from composer + return status::StatusBadBuffer; } pp->add_flags(packet::Packet::FlagComposed); @@ -269,17 +261,16 @@ status::StatusCode BlockWriter::make_repair_packet_(packet::seqnum_t pack_n, return status::StatusNoMem; } - status::StatusCode status = - repair_composer_.align(buffer, 0, block_encoder_.buffer_alignment()); - if (status != status::StatusOK) { + if (!repair_composer_.align(buffer, 0, block_encoder_.buffer_alignment())) { roc_log(LogError, "fec block writer: can't align packet buffer"); - return status; + // TODO(gh-183): forward status from composer + return status::StatusBadBuffer; } - status = repair_composer_.prepare(*packet, buffer, cur_payload_size_); - if (status != status::StatusOK) { + if (!repair_composer_.prepare(*packet, buffer, cur_payload_size_)) { roc_log(LogError, "fec block writer: can't prepare packet"); - return status; + // TODO(gh-183): forward status from composer + return status::StatusBadBuffer; } packet->add_flags(packet::Packet::FlagPrepared); @@ -313,10 +304,9 @@ status::StatusCode BlockWriter::compose_repair_packets_() { continue; } - status::StatusCode status = repair_composer_.compose(*rp); - if (status != status::StatusOK) { - roc_log(LogError, "fec block writer: can't compose packet"); - return status; + if (!repair_composer_.compose(*rp)) { + // TODO(gh-183): forward status from composer + return status::StatusBadBuffer; } rp->add_flags(packet::Packet::FlagComposed); } diff --git a/src/internal_modules/roc_fec/block_writer.h b/src/internal_modules/roc_fec/block_writer.h index d32017836..365e27921 100644 --- a/src/internal_modules/roc_fec/block_writer.h +++ b/src/internal_modules/roc_fec/block_writer.h @@ -68,13 +68,13 @@ class BlockWriter : public packet::IWriter, public core::NonCopyable<> { //! Set number of source packets per block. //! @note //! Actual reallocation may happen later. - ROC_NODISCARD status::StatusCode resize(size_t sblen, size_t rblen); + ROC_ATTR_NODISCARD status::StatusCode resize(size_t sblen, size_t rblen); //! Write packet. //! @remarks //! - writes the given source packet to the output writer //! - generates repair packets and also writes them to the output writer - virtual ROC_NODISCARD status::StatusCode write(const packet::PacketPtr&); + virtual ROC_ATTR_NODISCARD status::StatusCode write(const packet::PacketPtr&); private: status::StatusCode begin_block_(const packet::PacketPtr& pp); diff --git a/src/internal_modules/roc_fec/codec_map.cpp b/src/internal_modules/roc_fec/codec_map.cpp index 11efd1232..96c6e6717 100644 --- a/src/internal_modules/roc_fec/codec_map.cpp +++ b/src/internal_modules/roc_fec/codec_map.cpp @@ -24,9 +24,9 @@ namespace fec { namespace { template -ROC_NOUNUSED I* ctor_func(const CodecConfig& config, - packet::PacketFactory& packet_factory, - core::IArena& arena) { +ROC_ATTR_UNUSED I* ctor_func(const CodecConfig& config, + packet::PacketFactory& packet_factory, + core::IArena& arena) { return new (arena) T(config, packet_factory, arena); } diff --git a/src/internal_modules/roc_fec/composer.h b/src/internal_modules/roc_fec/composer.h index 753def05d..78b9ff107 100644 --- a/src/internal_modules/roc_fec/composer.h +++ b/src/internal_modules/roc_fec/composer.h @@ -36,12 +36,12 @@ class Composer : public packet::IComposer, public core::NonCopyable<> { } //! Check if the object was successfully constructed. - ROC_NODISCARD virtual status::StatusCode init_status() const { + virtual status::StatusCode init_status() const { return status::StatusOK; } //! Adjust buffer to align payload. - ROC_NODISCARD virtual status::StatusCode + virtual bool align(core::Slice& buffer, size_t header_size, size_t payload_alignment) { if ((unsigned long)buffer.data() % payload_alignment != 0) { roc_panic("fec composer: unexpected non-aligned buffer"); @@ -59,18 +59,18 @@ class Composer : public packet::IComposer, public core::NonCopyable<> { LogDebug, "fec composer: not enough space for alignment: padding=%lu cap=%lu", (unsigned long)padding, (unsigned long)buffer.capacity()); - return status::StatusBadBuffer; + return false; } buffer.reslice(padding, padding); - return status::StatusOK; + return true; } else { return inner_composer_->align(buffer, header_size, payload_alignment); } } //! Prepare buffer for composing a packet. - ROC_NODISCARD virtual status::StatusCode + virtual bool prepare(packet::Packet& packet, core::Slice& buffer, size_t payload_size) { core::Slice payload_id = buffer.subslice(0, 0); @@ -80,7 +80,7 @@ class Composer : public packet::IComposer, public core::NonCopyable<> { "fec composer: not enough space for fec header: size=%lu cap=%lu", (unsigned long)sizeof(PayloadID), (unsigned long)payload_id.capacity()); - return status::StatusBadBuffer; + return false; } payload_id.reslice(0, sizeof(PayloadID)); } @@ -89,10 +89,8 @@ class Composer : public packet::IComposer, public core::NonCopyable<> { payload_id.subslice(payload_id.size(), payload_id.size()); if (inner_composer_) { - status::StatusCode result = - inner_composer_->prepare(packet, payload, payload_size); - if (result != status::StatusOK) { - return result; + if (!inner_composer_->prepare(packet, payload, payload_size)) { + return false; } } else { payload.reslice(0, payload_size); @@ -106,7 +104,7 @@ class Composer : public packet::IComposer, public core::NonCopyable<> { "fec composer: not enough space for fec header: size=%lu cap=%lu", (unsigned long)sizeof(PayloadID), (unsigned long)payload_id.capacity()); - return status::StatusBadBuffer; + return false; } payload_id.reslice(0, sizeof(PayloadID)); } @@ -125,22 +123,21 @@ class Composer : public packet::IComposer, public core::NonCopyable<> { buffer.reslice(0, payload_id.size() + payload.size()); - return status::StatusOK; + return true; } //! Pad packet. - ROC_NODISCARD virtual status::StatusCode pad(packet::Packet& packet, - size_t padding_size) { + virtual bool pad(packet::Packet& packet, size_t padding_size) { if (inner_composer_) { return inner_composer_->pad(packet, padding_size); } // padding not supported - return status::StatusBadOperation; + return false; } //! Compose packet to buffer. - ROC_NODISCARD virtual status::StatusCode compose(packet::Packet& packet) { + virtual bool compose(packet::Packet& packet) { if (!packet.fec()) { roc_panic("fec composer: unexpected non-fec packet"); } @@ -170,7 +167,7 @@ class Composer : public packet::IComposer, public core::NonCopyable<> { return inner_composer_->compose(packet); } - return status::StatusOK; + return true; } private: diff --git a/src/internal_modules/roc_fec/headers.h b/src/internal_modules/roc_fec/headers.h index 283f44edd..926f51c0e 100644 --- a/src/internal_modules/roc_fec/headers.h +++ b/src/internal_modules/roc_fec/headers.h @@ -46,7 +46,7 @@ enum PayloadID_Pos { //! | Source Block Length (k) | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class LDPC_Source_PayloadID { +ROC_ATTR_PACKED_BEGIN class LDPC_Source_PayloadID { private: //! Source block number. uint16_t sbn_; @@ -106,7 +106,7 @@ ROC_PACKED_BEGIN class LDPC_Source_PayloadID { //! Set number encoding symbols. void set_n(uint16_t) { } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! LDPC-Staircase Repair FEC Payload ID. //! @@ -121,7 +121,7 @@ ROC_PACKED_BEGIN class LDPC_Source_PayloadID { //! | Source Block Length (k) | Number Encoding Symbols (n) | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class LDPC_Repair_PayloadID { +ROC_ATTR_PACKED_BEGIN class LDPC_Repair_PayloadID { private: //! Source block number. uint16_t sbn_; @@ -185,7 +185,7 @@ ROC_PACKED_BEGIN class LDPC_Repair_PayloadID { void set_n(uint16_t val) { n_ = core::hton16u(val); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! Reed-Solomon Source or Repair Payload ID (for m=8). //! @@ -200,7 +200,7 @@ ROC_PACKED_BEGIN class LDPC_Repair_PayloadID { //! | Source Block Length (k) | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class RS8M_PayloadID { +ROC_ATTR_PACKED_BEGIN class RS8M_PayloadID { private: //! Source block number. uint8_t sbn_[3]; @@ -264,7 +264,7 @@ ROC_PACKED_BEGIN class RS8M_PayloadID { //! Set number encoding symbols. void set_n(uint16_t) { } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; } // namespace fec } // namespace roc diff --git a/src/internal_modules/roc_fec/iblock_decoder.h b/src/internal_modules/roc_fec/iblock_decoder.h index 0c56b53ab..6c71e7536 100644 --- a/src/internal_modules/roc_fec/iblock_decoder.h +++ b/src/internal_modules/roc_fec/iblock_decoder.h @@ -40,7 +40,7 @@ class IBlockDecoder : public core::ArenaAllocation { //! any operations for the block. //! @returns status::StatusOK on success, or a specific error code on failure (e.g., //! status::StatusNoMem if memory allocation fails). - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode begin_block(size_t sblen, size_t rblen, size_t payload_size) = 0; //! Store source or repair packet buffer for current block. diff --git a/src/internal_modules/roc_fec/iblock_encoder.h b/src/internal_modules/roc_fec/iblock_encoder.h index e73db3212..46cb538fc 100644 --- a/src/internal_modules/roc_fec/iblock_encoder.h +++ b/src/internal_modules/roc_fec/iblock_encoder.h @@ -43,7 +43,7 @@ class IBlockEncoder : public core::ArenaAllocation { //! the block. //! @returns status::StatusOK on success, or a specific error code on failure (e.g., //! status::StatusNoMem if memory allocation fails). - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode begin_block(size_t sblen, size_t rblen, size_t payload_size) = 0; //! Store source or repair packet buffer for current block. diff --git a/src/internal_modules/roc_fec/parser.h b/src/internal_modules/roc_fec/parser.h index 0ae1ca3bf..571b67d8e 100644 --- a/src/internal_modules/roc_fec/parser.h +++ b/src/internal_modules/roc_fec/parser.h @@ -39,12 +39,11 @@ class Parser : public packet::IParser, public core::NonCopyable<> { } //! Parse packet from buffer. - virtual ROC_NODISCARD status::StatusCode parse(packet::Packet& packet, - const core::Slice& buffer) { + virtual bool parse(packet::Packet& packet, const core::Slice& buffer) { if (buffer.size() < sizeof(PayloadID)) { roc_log(LogDebug, "fec parser: bad packet, size < %d (payload id)", (int)sizeof(PayloadID)); - return status::StatusBadPacket; + return false; } const PayloadID* payload_id; @@ -79,7 +78,7 @@ class Parser : public packet::IParser, public core::NonCopyable<> { return inner_parser_->parse(packet, fec.payload); } - return status::StatusOK; + return true; } private: diff --git a/src/internal_modules/roc_fec/target_openfec/roc_fec/openfec_decoder.h b/src/internal_modules/roc_fec/target_openfec/roc_fec/openfec_decoder.h index 8c36f51f9..5b99abd0a 100644 --- a/src/internal_modules/roc_fec/target_openfec/roc_fec/openfec_decoder.h +++ b/src/internal_modules/roc_fec/target_openfec/roc_fec/openfec_decoder.h @@ -45,7 +45,7 @@ class OpenfecDecoder : public IBlockDecoder, public core::NonCopyable<> { virtual size_t max_block_length() const; //! Start block. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode begin_block(size_t sblen, size_t rblen, size_t payload_size); //! Store source or repair packet buffer for current block. diff --git a/src/internal_modules/roc_fec/target_openfec/roc_fec/openfec_encoder.h b/src/internal_modules/roc_fec/target_openfec/roc_fec/openfec_encoder.h index ee1f43b50..7f9fe659f 100644 --- a/src/internal_modules/roc_fec/target_openfec/roc_fec/openfec_encoder.h +++ b/src/internal_modules/roc_fec/target_openfec/roc_fec/openfec_encoder.h @@ -48,7 +48,7 @@ class OpenfecEncoder : public IBlockEncoder, public core::NonCopyable<> { virtual size_t buffer_alignment() const; //! Start block. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode begin_block(size_t sblen, size_t rblen, size_t payload_size); //! Store packet data for current block. diff --git a/src/internal_modules/roc_netio/target_libuv/roc_netio/network_loop.h b/src/internal_modules/roc_netio/target_libuv/roc_netio/network_loop.h index 41e0914fc..cfaedc895 100644 --- a/src/internal_modules/roc_netio/target_libuv/roc_netio/network_loop.h +++ b/src/internal_modules/roc_netio/target_libuv/roc_netio/network_loop.h @@ -213,7 +213,7 @@ class NetworkLoop : private ITerminateHandler, //! Should not be called from schedule() callback. //! @returns //! true if the task succeeded or false if it failed. - ROC_NODISCARD bool schedule_and_wait(NetworkTask& task); + ROC_ATTR_NODISCARD bool schedule_and_wait(NetworkTask& task); private: static void task_sem_cb_(uv_async_t* handle); diff --git a/src/internal_modules/roc_netio/target_libuv/roc_netio/resolver.cpp b/src/internal_modules/roc_netio/target_libuv/roc_netio/resolver.cpp index 857d55d2a..23a846725 100644 --- a/src/internal_modules/roc_netio/target_libuv/roc_netio/resolver.cpp +++ b/src/internal_modules/roc_netio/target_libuv/roc_netio/resolver.cpp @@ -27,7 +27,7 @@ bool Resolver::async_resolve(ResolverRequest& req) { req.resolved_address.clear(); - if (!req.endpoint_uri->is_valid()) { + if (!req.endpoint_uri->verify(address::NetworkUri::Subset_Full)) { roc_log(LogError, "resolver: invalid endpoint"); req.success = false; return false; @@ -44,12 +44,9 @@ bool Resolver::async_resolve(ResolverRequest& req) { req.handle.data = this; - char fmt_port[6] = {}; - core::StringBuilder sb(fmt_port, sizeof(fmt_port)); - sb.append_sint(req.endpoint_uri->port_or_default(), 10); - - if (int err = uv_getaddrinfo(&loop_, &req.handle, &Resolver::getaddrinfo_cb_, - req.endpoint_uri->host(), fmt_port, NULL)) { + if (int err = + uv_getaddrinfo(&loop_, &req.handle, &Resolver::getaddrinfo_cb_, + req.endpoint_uri->host(), req.endpoint_uri->service(), NULL)) { finish_resolving_(req, err); return false; } diff --git a/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp b/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp index 83d3222bc..fda41007e 100644 --- a/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp +++ b/src/internal_modules/roc_netio/target_libuv/roc_netio/udp_port.cpp @@ -74,7 +74,7 @@ bool UdpPort::open() { handle_initialized_ = true; unsigned flags = 0; - if ((config_.enable_reuseaddr || config_.bind_address.is_multicast()) + if ((config_.enable_reuseaddr || config_.bind_address.multicast()) && config_.bind_address.port() > 0) { flags |= UV_UDP_REUSEADDR; } @@ -520,7 +520,7 @@ void UdpPort::start_closing_() { } bool UdpPort::join_multicast_group_() { - if (!config_.bind_address.is_multicast()) { + if (!config_.bind_address.multicast()) { roc_log(LogError, "udp port: %s: can't use multicast group for non-multicast address", descriptor()); diff --git a/src/internal_modules/roc_netio/target_posix/roc_netio/socket_ops.h b/src/internal_modules/roc_netio/target_posix/roc_netio/socket_ops.h index 8393e7dff..26e6cbbda 100644 --- a/src/internal_modules/roc_netio/target_posix/roc_netio/socket_ops.h +++ b/src/internal_modules/roc_netio/target_posix/roc_netio/socket_ops.h @@ -54,59 +54,62 @@ typedef int SocketHandle; const SocketHandle SocketInvalid = -1; //! Create non-blocking socket. -ROC_NODISCARD bool +ROC_ATTR_NODISCARD bool socket_create(address::AddrFamily family, SocketType type, SocketHandle& new_sock); //! Accept incoming connection. -ROC_NODISCARD bool socket_accept(SocketHandle sock, - SocketHandle& new_sock, - address::SocketAddr& remote_address); +ROC_ATTR_NODISCARD bool socket_accept(SocketHandle sock, + SocketHandle& new_sock, + address::SocketAddr& remote_address); //! Set socket options. -ROC_NODISCARD bool socket_setup(SocketHandle sock, const SocketOpts& options); +ROC_ATTR_NODISCARD bool socket_setup(SocketHandle sock, const SocketOpts& options); //! Bind socket to local address. -ROC_NODISCARD bool socket_bind(SocketHandle sock, address::SocketAddr& local_address); +ROC_ATTR_NODISCARD bool socket_bind(SocketHandle sock, + address::SocketAddr& local_address); //! Start listening for incoming connections. -ROC_NODISCARD bool socket_listen(SocketHandle sock, size_t backlog); +ROC_ATTR_NODISCARD bool socket_listen(SocketHandle sock, size_t backlog); //! Initiate connecting to remote peer. //! @returns true if connection was successfully initiated. //! Sets @p completed_immediately to true if connection was established //! immediately and there is no need to wait for it. -ROC_NODISCARD bool socket_begin_connect(SocketHandle sock, - const address::SocketAddr& remote_address, - bool& completed_immediately); +ROC_ATTR_NODISCARD bool socket_begin_connect(SocketHandle sock, + const address::SocketAddr& remote_address, + bool& completed_immediately); //! Finish connecting to remote peer. //! @returns true if connection was successfully established. -ROC_NODISCARD bool socket_end_connect(SocketHandle sock); +ROC_ATTR_NODISCARD bool socket_end_connect(SocketHandle sock); //! Try to read bytes from socket without blocking. //! @returns number of bytes read (>= 0) or SocketError (< 0). -ROC_NODISCARD ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz); +ROC_ATTR_NODISCARD ssize_t socket_try_recv(SocketHandle sock, void* buf, size_t bufsz); //! Try to write bytes to socket without blocking. //! @returns number of bytes written (>= 0) or SocketError (< 0). -ROC_NODISCARD ssize_t socket_try_send(SocketHandle sock, const void* buf, size_t bufsz); +ROC_ATTR_NODISCARD ssize_t socket_try_send(SocketHandle sock, + const void* buf, + size_t bufsz); //! Try to send datagram via socket to given address, without blocking. //! @returns number of bytes written (>= 0) or SocketError (< 0). -ROC_NODISCARD ssize_t socket_try_send_to(SocketHandle sock, - const void* buf, - size_t bufsz, - const address::SocketAddr& remote_address); +ROC_ATTR_NODISCARD ssize_t socket_try_send_to(SocketHandle sock, + const void* buf, + size_t bufsz, + const address::SocketAddr& remote_address); //! Gracefully shutdown connection. -ROC_NODISCARD bool socket_shutdown(SocketHandle sock); +ROC_ATTR_NODISCARD bool socket_shutdown(SocketHandle sock); //! Close socket. -ROC_NODISCARD bool socket_close(SocketHandle sock); +ROC_ATTR_NODISCARD bool socket_close(SocketHandle sock); //! Close socket and send reset to remote peer. //! Remote peer will get error when reading from connection. -ROC_NODISCARD bool socket_close_with_reset(SocketHandle sock); +ROC_ATTR_NODISCARD bool socket_close_with_reset(SocketHandle sock); } // namespace netio } // namespace roc diff --git a/src/internal_modules/roc_node/receiver.cpp b/src/internal_modules/roc_node/receiver.cpp index 770d76add..ca4d13deb 100644 --- a/src/internal_modules/roc_node/receiver.cpp +++ b/src/internal_modules/roc_node/receiver.cpp @@ -142,7 +142,7 @@ bool Receiver::bind(slot_index_t slot_index, return false; } - if (!uri.is_valid()) { + if (!uri.verify(address::NetworkUri::Subset_Full)) { roc_log(LogError, "receiver node:" " can't bind %s interface of slot %lu:" diff --git a/src/internal_modules/roc_node/receiver.h b/src/internal_modules/roc_node/receiver.h index 52a0194f6..d37d60963 100644 --- a/src/internal_modules/roc_node/receiver.h +++ b/src/internal_modules/roc_node/receiver.h @@ -46,16 +46,16 @@ class Receiver : public Node, private pipeline::IPipelineTaskScheduler { status::StatusCode init_status() const; //! Set interface config. - ROC_NODISCARD bool configure(slot_index_t slot_index, - address::Interface iface, - const netio::UdpConfig& config); + ROC_ATTR_NODISCARD bool configure(slot_index_t slot_index, + address::Interface iface, + const netio::UdpConfig& config); //! Bind to local endpoint. - ROC_NODISCARD bool + ROC_ATTR_NODISCARD bool bind(slot_index_t slot_index, address::Interface iface, address::NetworkUri& uri); //! Remove slot. - ROC_NODISCARD bool unlink(slot_index_t slot_index); + ROC_ATTR_NODISCARD bool unlink(slot_index_t slot_index); //! Callback for slot metrics. typedef void (*slot_metrics_func_t)(const pipeline::ReceiverSlotMetrics& slot_metrics, @@ -68,12 +68,12 @@ class Receiver : public Node, private pipeline::IPipelineTaskScheduler { void* party_arg); //! Get metrics. - ROC_NODISCARD bool get_metrics(slot_index_t slot_index, - slot_metrics_func_t slot_metrics_func, - void* slot_metrics_arg, - party_metrics_func_t party_metrics_func, - size_t* party_metrics_size, - void* party_metrics_arg); + ROC_ATTR_NODISCARD bool get_metrics(slot_index_t slot_index, + slot_metrics_func_t slot_metrics_func, + void* slot_metrics_arg, + party_metrics_func_t party_metrics_func, + size_t* party_metrics_size, + void* party_metrics_arg); //! Check if there are broken slots. bool has_broken_slots(); @@ -82,7 +82,7 @@ class Receiver : public Node, private pipeline::IPipelineTaskScheduler { //! @remarks //! Performs necessary checks and allocations on top of ISource::read(), //! used when working with raw byte buffers instead of Frame objects. - ROC_NODISCARD status::StatusCode read_frame(void* bytes, size_t n_bytes); + ROC_ATTR_NODISCARD status::StatusCode read_frame(void* bytes, size_t n_bytes); //! Get receiver source. sndio::ISource& source(); diff --git a/src/internal_modules/roc_node/receiver_decoder.h b/src/internal_modules/roc_node/receiver_decoder.h index 556010650..2ec4abf4c 100644 --- a/src/internal_modules/roc_node/receiver_decoder.h +++ b/src/internal_modules/roc_node/receiver_decoder.h @@ -41,7 +41,7 @@ class ReceiverDecoder : public Node, private pipeline::IPipelineTaskScheduler { status::StatusCode init_status() const; //! Activate interface. - ROC_NODISCARD bool activate(address::Interface iface, address::Protocol proto); + ROC_ATTR_NODISCARD bool activate(address::Interface iface, address::Protocol proto); //! Callback for slot metrics. typedef void (*slot_metrics_func_t)(const pipeline::ReceiverSlotMetrics& slot_metrics, @@ -54,26 +54,26 @@ class ReceiverDecoder : public Node, private pipeline::IPipelineTaskScheduler { void* party_arg); //! Get metrics. - ROC_NODISCARD bool get_metrics(slot_metrics_func_t slot_metrics_func, - void* slot_metrics_arg, - party_metrics_func_t party_metrics_func, - void* party_metrics_arg); + ROC_ATTR_NODISCARD bool get_metrics(slot_metrics_func_t slot_metrics_func, + void* slot_metrics_arg, + party_metrics_func_t party_metrics_func, + void* party_metrics_arg); //! Write packet for decoding. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode write_packet(address::Interface iface, const void* bytes, size_t n_bytes); //! Read encoded packet. //! @note //! Typically used to generate control packets with feedback for sender. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode read_packet(address::Interface iface, void* bytes, size_t* n_bytes); //! Read frame into byte buffer. //! @remarks //! Performs necessary checks and allocations on top of ISource::read(), //! needed when working with byte buffers instead of Frame objects. - ROC_NODISCARD status::StatusCode read_frame(void* bytes, size_t n_bytes); + ROC_ATTR_NODISCARD status::StatusCode read_frame(void* bytes, size_t n_bytes); //! Source for reading decoded frames. sndio::ISource& source(); diff --git a/src/internal_modules/roc_node/sender.cpp b/src/internal_modules/roc_node/sender.cpp index 8dd52c540..6c9949e8c 100644 --- a/src/internal_modules/roc_node/sender.cpp +++ b/src/internal_modules/roc_node/sender.cpp @@ -144,7 +144,7 @@ bool Sender::connect(slot_index_t slot_index, return false; } - if (!uri.is_valid()) { + if (!uri.verify(address::NetworkUri::Subset_Full)) { roc_log(LogError, "sender node: can't connect %s interface of slot %lu: invalid uri", address::interface_to_str(iface), (unsigned long)slot_index); diff --git a/src/internal_modules/roc_node/sender.h b/src/internal_modules/roc_node/sender.h index 99ae214ad..b42a796fd 100644 --- a/src/internal_modules/roc_node/sender.h +++ b/src/internal_modules/roc_node/sender.h @@ -47,17 +47,17 @@ class Sender : public Node, private pipeline::IPipelineTaskScheduler { status::StatusCode init_status() const; //! Set interface config. - ROC_NODISCARD bool configure(slot_index_t slot_index, - address::Interface iface, - const netio::UdpConfig& config); + ROC_ATTR_NODISCARD bool configure(slot_index_t slot_index, + address::Interface iface, + const netio::UdpConfig& config); //! Connect to remote endpoint. - ROC_NODISCARD bool connect(slot_index_t slot_index, - address::Interface iface, - const address::NetworkUri& uri); + ROC_ATTR_NODISCARD bool connect(slot_index_t slot_index, + address::Interface iface, + const address::NetworkUri& uri); //! Remove slot. - ROC_NODISCARD bool unlink(slot_index_t slot_index); + ROC_ATTR_NODISCARD bool unlink(slot_index_t slot_index); //! Callback for slot metrics. typedef void (*slot_metrics_func_t)(const pipeline::SenderSlotMetrics& slot_metrics, @@ -70,12 +70,12 @@ class Sender : public Node, private pipeline::IPipelineTaskScheduler { void* party_arg); //! Get metrics. - ROC_NODISCARD bool get_metrics(slot_index_t slot_index, - slot_metrics_func_t slot_metrics_func, - void* slot_metrics_arg, - party_metrics_func_t party_metrics_func, - size_t* party_metrics_size, - void* party_metrics_arg); + ROC_ATTR_NODISCARD bool get_metrics(slot_index_t slot_index, + slot_metrics_func_t slot_metrics_func, + void* slot_metrics_arg, + party_metrics_func_t party_metrics_func, + size_t* party_metrics_size, + void* party_metrics_arg); //! Check if there are incomplete or broken slots. bool has_incomplete_slots(); @@ -87,7 +87,7 @@ class Sender : public Node, private pipeline::IPipelineTaskScheduler { //! @remarks //! Performs necessary checks and allocations on top of ISink::write(), //! needed when working with byte buffers instead of Frame objects. - ROC_NODISCARD status::StatusCode write_frame(const void* bytes, size_t n_bytes); + ROC_ATTR_NODISCARD status::StatusCode write_frame(const void* bytes, size_t n_bytes); //! Get sender sink. sndio::ISink& sink(); diff --git a/src/internal_modules/roc_node/sender_encoder.h b/src/internal_modules/roc_node/sender_encoder.h index 0ff840836..ff97bf9e1 100644 --- a/src/internal_modules/roc_node/sender_encoder.h +++ b/src/internal_modules/roc_node/sender_encoder.h @@ -46,7 +46,7 @@ class SenderEncoder : public Node, private pipeline::IPipelineTaskScheduler { packet::PacketFactory& packet_factory(); //! Activate interface. - ROC_NODISCARD bool activate(address::Interface iface, address::Protocol proto); + ROC_ATTR_NODISCARD bool activate(address::Interface iface, address::Protocol proto); //! Callback for slot metrics. typedef void (*slot_metrics_func_t)(const pipeline::SenderSlotMetrics& slot_metrics, @@ -59,29 +59,29 @@ class SenderEncoder : public Node, private pipeline::IPipelineTaskScheduler { void* party_arg); //! Get metrics. - ROC_NODISCARD bool get_metrics(slot_metrics_func_t slot_metrics_func, - void* slot_metrics_arg, - party_metrics_func_t party_metrics_func, - void* party_metrics_arg); + ROC_ATTR_NODISCARD bool get_metrics(slot_metrics_func_t slot_metrics_func, + void* slot_metrics_arg, + party_metrics_func_t party_metrics_func, + void* party_metrics_arg); //! Check if everything is connected. bool is_complete(); //! Read encoded packet. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode read_packet(address::Interface iface, void* bytes, size_t* n_bytes); //! Write packet for decoding. //! @note //! Typically used to deliver control packets with receiver feedback. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode write_packet(address::Interface iface, const void* bytes, size_t n_bytes); //! Write frame. //! @remarks //! Performs necessary checks and allocations on top of ISink::write(), //! needed when working with byte buffers instead of Frame objects. - ROC_NODISCARD status::StatusCode write_frame(const void* bytes, size_t n_bytes); + ROC_ATTR_NODISCARD status::StatusCode write_frame(const void* bytes, size_t n_bytes); //! Sink for writing frames for encoding. sndio::ISink& sink(); diff --git a/src/internal_modules/roc_packet/concurrent_queue.h b/src/internal_modules/roc_packet/concurrent_queue.h index 360d6f627..24be31b89 100644 --- a/src/internal_modules/roc_packet/concurrent_queue.h +++ b/src/internal_modules/roc_packet/concurrent_queue.h @@ -44,13 +44,14 @@ class ConcurrentQueue : public IWriter, public IReader, public core::NonCopyable //! Add packet to the queue. //! Wait-free operation. - virtual ROC_NODISCARD status::StatusCode write(const PacketPtr& packet); + virtual ROC_ATTR_NODISCARD status::StatusCode write(const PacketPtr& packet); //! Read next packet. //! If queue is blocking, blocks until queue is non-empty. //! If queue is non-blocking, and there are no concurrent read calls, //! then read is a lock-free and wait-free operation. - virtual ROC_NODISCARD status::StatusCode read(PacketPtr& packet, PacketReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode read(PacketPtr& packet, + PacketReadMode mode); private: core::Optional write_sem_; diff --git a/src/internal_modules/roc_packet/delayed_reader.h b/src/internal_modules/roc_packet/delayed_reader.h index a6fab01e5..98b128f8c 100644 --- a/src/internal_modules/roc_packet/delayed_reader.h +++ b/src/internal_modules/roc_packet/delayed_reader.h @@ -62,7 +62,8 @@ class DelayedReader : public IReader, public core::NonCopyable<> { status::StatusCode init_status() const; //! Read packet. - virtual ROC_NODISCARD status::StatusCode read(PacketPtr& packet, PacketReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode read(PacketPtr& packet, + PacketReadMode mode); private: status::StatusCode load_queue_(); diff --git a/src/internal_modules/roc_packet/fifo_queue.h b/src/internal_modules/roc_packet/fifo_queue.h index 947e9d856..4352c3229 100644 --- a/src/internal_modules/roc_packet/fifo_queue.h +++ b/src/internal_modules/roc_packet/fifo_queue.h @@ -51,10 +51,11 @@ class FifoQueue : public IWriter, public IReader, public core::NonCopyable<> { //! Add packet to the queue. //! @remarks //! Adds packet to the end of the queue. - virtual ROC_NODISCARD status::StatusCode write(const PacketPtr& packet); + virtual ROC_ATTR_NODISCARD status::StatusCode write(const PacketPtr& packet); //! Read next packet. - virtual ROC_NODISCARD status::StatusCode read(PacketPtr& packet, PacketReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode read(PacketPtr& packet, + PacketReadMode mode); private: core::List list_; diff --git a/src/internal_modules/roc_packet/icomposer.h b/src/internal_modules/roc_packet/icomposer.h index c067f7990..311b1ccf3 100644 --- a/src/internal_modules/roc_packet/icomposer.h +++ b/src/internal_modules/roc_packet/icomposer.h @@ -32,7 +32,7 @@ class IComposer : public core::ArenaAllocation { //! @returns //! status::StatusOK if composer was initialized correctly, //! or error code otherwise. - ROC_NODISCARD virtual status::StatusCode init_status() const = 0; + virtual status::StatusCode init_status() const = 0; //! Adjust buffer to align payload. //! @remarks @@ -42,7 +42,7 @@ class IComposer : public core::ArenaAllocation { //! @returns //! true if the buffer was successfully adjusted or false if the @p buffer //! capacity is not enough. - ROC_NODISCARD virtual status::StatusCode + virtual bool align(core::Slice& buffer, size_t header_size, size_t payload_alignment) = 0; //! Prepare buffer for composing a packet. @@ -55,7 +55,7 @@ class IComposer : public core::ArenaAllocation { //! @returns //! true if the packet was successfully prepared or false if the @p buffer //! capacity is not enough. - ROC_NODISCARD virtual status::StatusCode + virtual bool prepare(Packet& packet, core::Slice& buffer, size_t payload_size) = 0; //! Pad packet. @@ -66,7 +66,7 @@ class IComposer : public core::ArenaAllocation { //! @returns //! true if the packet was successfully padded or false if parameters //! are invalid or padding is not supported. - ROC_NODISCARD virtual status::StatusCode pad(Packet& packet, size_t padding_size) = 0; + virtual bool pad(Packet& packet, size_t padding_size) = 0; //! Compose packet to buffer. //! @remarks @@ -74,7 +74,7 @@ class IComposer : public core::ArenaAllocation { //! a previous prepare() call. //! @returns //! true if the packet was successfully composed or false if an error occurred. - ROC_NODISCARD virtual status::StatusCode compose(Packet& packet) = 0; + virtual bool compose(Packet& packet) = 0; }; } // namespace packet diff --git a/src/internal_modules/roc_packet/interleaver.cpp b/src/internal_modules/roc_packet/interleaver.cpp index 0f1bf2e92..142c9ffc7 100644 --- a/src/internal_modules/roc_packet/interleaver.cpp +++ b/src/internal_modules/roc_packet/interleaver.cpp @@ -9,6 +9,7 @@ #include "roc_packet/interleaver.h" #include "roc_core/fast_random.h" #include "roc_core/log.h" +#include "roc_status/code_to_str.h" namespace roc { namespace packet { diff --git a/src/internal_modules/roc_packet/interleaver.h b/src/internal_modules/roc_packet/interleaver.h index 0decd1a6d..1cce9a8c2 100644 --- a/src/internal_modules/roc_packet/interleaver.h +++ b/src/internal_modules/roc_packet/interleaver.h @@ -37,10 +37,10 @@ class Interleaver : public IWriter, public core::NonCopyable<> { //! @remarks //! Packets are written to internal buffer. Buffered packets are //! then reordered and sent to output writer. - virtual ROC_NODISCARD status::StatusCode write(const PacketPtr& packet); + virtual ROC_ATTR_NODISCARD status::StatusCode write(const PacketPtr& packet); //! Send all buffered packets to output writer. - ROC_NODISCARD status::StatusCode flush(); + ROC_ATTR_NODISCARD status::StatusCode flush(); //! Maximum delay between writing packet and moment we get it in output //! in terms of packets number. diff --git a/src/internal_modules/roc_packet/iparser.h b/src/internal_modules/roc_packet/iparser.h index b6dae1d42..9f5d55a32 100644 --- a/src/internal_modules/roc_packet/iparser.h +++ b/src/internal_modules/roc_packet/iparser.h @@ -13,7 +13,6 @@ #define ROC_PACKET_IPARSER_H_ #include "roc_core/allocation_policy.h" -#include "roc_core/attributes.h" #include "roc_core/slice.h" #include "roc_packet/packet.h" #include "roc_status/status_code.h" @@ -41,10 +40,8 @@ class IParser : public core::ArenaAllocation { //! Parses input @p buffer and fills @p packet. If the packet payload contains //! an inner packet, calls the inner parser as well. //! @returns - //! status::StatusOK if the packet was successfully parsed, - //! or error code otherwise. - virtual ROC_NODISCARD status::StatusCode - parse(Packet& packet, const core::Slice& buffer) = 0; + //! true if the packet was successfully parsed or false if the packet is invalid. + virtual bool parse(Packet& packet, const core::Slice& buffer) = 0; }; } // namespace packet diff --git a/src/internal_modules/roc_packet/ireader.h b/src/internal_modules/roc_packet/ireader.h index 8ee698647..b1b5a9ff7 100644 --- a/src/internal_modules/roc_packet/ireader.h +++ b/src/internal_modules/roc_packet/ireader.h @@ -53,8 +53,8 @@ class IReader { //! - Otherwise, returns an error. //! //! @see status::StatusCode. - virtual ROC_NODISCARD status::StatusCode read(PacketPtr& packet, - PacketReadMode mode) = 0; + virtual ROC_ATTR_NODISCARD status::StatusCode read(PacketPtr& packet, + PacketReadMode mode) = 0; }; } // namespace packet diff --git a/src/internal_modules/roc_packet/iwriter.h b/src/internal_modules/roc_packet/iwriter.h index e96f55162..590e107f3 100644 --- a/src/internal_modules/roc_packet/iwriter.h +++ b/src/internal_modules/roc_packet/iwriter.h @@ -37,7 +37,7 @@ class IWriter { //! e.g. part of the packet may be written. //! //! @see status::StatusCode. - virtual ROC_NODISCARD status::StatusCode write(const PacketPtr&) = 0; + virtual ROC_ATTR_NODISCARD status::StatusCode write(const PacketPtr&) = 0; }; } // namespace packet diff --git a/src/internal_modules/roc_packet/router.h b/src/internal_modules/roc_packet/router.h index 0521cce4a..19a3fb49a 100644 --- a/src/internal_modules/roc_packet/router.h +++ b/src/internal_modules/roc_packet/router.h @@ -46,7 +46,7 @@ class Router : public IWriter, public core::NonCopyable<> { //! Add route. //! @remarks //! Packets that has given @p flags set will be routed to @p writer. - ROC_NODISCARD status::StatusCode add_route(IWriter& writer, unsigned flags); + ROC_ATTR_NODISCARD status::StatusCode add_route(IWriter& writer, unsigned flags); //! Check if there is detected source id for given route. //! @remarks @@ -63,7 +63,7 @@ class Router : public IWriter, public core::NonCopyable<> { //! Write next packet. //! @remarks //! Route @p packet to a writer or drop it if no routes found. - virtual ROC_NODISCARD status::StatusCode write(const PacketPtr& packet); + virtual ROC_ATTR_NODISCARD status::StatusCode write(const PacketPtr& packet); private: struct Route { diff --git a/src/internal_modules/roc_packet/shipper.cpp b/src/internal_modules/roc_packet/shipper.cpp index 3f7542e2b..d7c16918c 100644 --- a/src/internal_modules/roc_packet/shipper.cpp +++ b/src/internal_modules/roc_packet/shipper.cpp @@ -46,10 +46,9 @@ status::StatusCode Shipper::write(const PacketPtr& packet) { } if (!packet->has_flags(Packet::FlagComposed)) { - status::StatusCode status = composer_.compose(*packet); - if (status != status::StatusOK) { + if (!composer_.compose(*packet)) { roc_log(LogError, "shipper: can't compose packet"); - return status; + return status::StatusNoMem; } packet->add_flags(Packet::FlagComposed); } diff --git a/src/internal_modules/roc_packet/shipper.h b/src/internal_modules/roc_packet/shipper.h index c2368484f..56eb93ce9 100644 --- a/src/internal_modules/roc_packet/shipper.h +++ b/src/internal_modules/roc_packet/shipper.h @@ -38,7 +38,7 @@ class Shipper : public IWriter, public core::NonCopyable<> { const address::SocketAddr& outbound_address() const; //! Write outgoing packet. - virtual ROC_NODISCARD status::StatusCode write(const PacketPtr& packet); + virtual ROC_ATTR_NODISCARD status::StatusCode write(const PacketPtr& packet); private: IComposer& composer_; diff --git a/src/internal_modules/roc_packet/sorted_queue.h b/src/internal_modules/roc_packet/sorted_queue.h index 6eeb3ce2f..72b0365b6 100644 --- a/src/internal_modules/roc_packet/sorted_queue.h +++ b/src/internal_modules/roc_packet/sorted_queue.h @@ -66,13 +66,14 @@ class SortedQueue : public IWriter, public IReader, public core::NonCopyable<> { //! - if the maximum queue size is reached, packet is dropped //! - if packet is equal to another packet in the queue, it is dropped //! - otherwise, packet is inserted into the queue, keeping the queue sorted - virtual ROC_NODISCARD status::StatusCode write(const PacketPtr& packet); + virtual ROC_ATTR_NODISCARD status::StatusCode write(const PacketPtr& packet); //! Read next packet. //! //! @remarks //! Removes returned packet from the queue. - virtual ROC_NODISCARD status::StatusCode read(PacketPtr& packet, PacketReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode read(PacketPtr& packet, + PacketReadMode mode); private: core::List list_; diff --git a/src/internal_modules/roc_pipeline/config.h b/src/internal_modules/roc_pipeline/config.h index a485633f8..6530591de 100644 --- a/src/internal_modules/roc_pipeline/config.h +++ b/src/internal_modules/roc_pipeline/config.h @@ -112,7 +112,7 @@ struct SenderSinkConfig { SenderSinkConfig(); //! Fill unset values with defaults. - ROC_NODISCARD bool deduce_defaults(audio::ProcessorMap& processor_map); + ROC_ATTR_NODISCARD bool deduce_defaults(audio::ProcessorMap& processor_map); }; //! Parameters of sender slot. @@ -121,7 +121,7 @@ struct SenderSlotConfig { SenderSlotConfig(); //! Fill unset values with defaults. - ROC_NODISCARD bool deduce_defaults(); + ROC_ATTR_NODISCARD bool deduce_defaults(); }; //! Parameters common for all receiver sessions. @@ -154,7 +154,7 @@ struct ReceiverCommonConfig { ReceiverCommonConfig(); //! Fill unset values with defaults. - ROC_NODISCARD bool deduce_defaults(audio::ProcessorMap& processor_map); + ROC_ATTR_NODISCARD bool deduce_defaults(audio::ProcessorMap& processor_map); }; //! Parameters of receiver session. @@ -190,7 +190,7 @@ struct ReceiverSessionConfig { ReceiverSessionConfig(); //! Fill unset values with defaults. - ROC_NODISCARD bool deduce_defaults(audio::ProcessorMap& processor_map); + ROC_ATTR_NODISCARD bool deduce_defaults(audio::ProcessorMap& processor_map); }; //! Parameters of receiver session. @@ -209,7 +209,7 @@ struct ReceiverSourceConfig { ReceiverSourceConfig(); //! Fill unset values with defaults. - ROC_NODISCARD bool deduce_defaults(audio::ProcessorMap& processor_map); + ROC_ATTR_NODISCARD bool deduce_defaults(audio::ProcessorMap& processor_map); }; //! Parameters of receiver slot. @@ -221,7 +221,7 @@ struct ReceiverSlotConfig { ReceiverSlotConfig(); //! Fill unset values with defaults. - ROC_NODISCARD bool deduce_defaults(); + ROC_ATTR_NODISCARD bool deduce_defaults(); }; //! Converter parameters. @@ -245,7 +245,7 @@ struct TranscoderConfig { TranscoderConfig(); //! Fill unset values with defaults. - ROC_NODISCARD bool deduce_defaults(audio::ProcessorMap& processor_map); + ROC_ATTR_NODISCARD bool deduce_defaults(audio::ProcessorMap& processor_map); }; } // namespace pipeline diff --git a/src/internal_modules/roc_pipeline/pipeline_loop.h b/src/internal_modules/roc_pipeline/pipeline_loop.h index fa688e7a9..90515b02b 100644 --- a/src/internal_modules/roc_pipeline/pipeline_loop.h +++ b/src/internal_modules/roc_pipeline/pipeline_loop.h @@ -306,7 +306,7 @@ class PipelineLoop : public core::NonCopyable<> { const Stats& stats_ref() const; //! Split frame and process subframes and some of the enqueued tasks. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode process_subframes_and_tasks(audio::Frame& frame, packet::stream_timestamp_t frame_duration, audio::FrameReadMode mode); diff --git a/src/internal_modules/roc_pipeline/receiver_endpoint.cpp b/src/internal_modules/roc_pipeline/receiver_endpoint.cpp index 056073dc3..210eabf5f 100644 --- a/src/internal_modules/roc_pipeline/receiver_endpoint.cpp +++ b/src/internal_modules/roc_pipeline/receiver_endpoint.cpp @@ -222,16 +222,12 @@ status::StatusCode ReceiverEndpoint::pull_packets(core::nanoseconds_t current_ti status::StatusCode ReceiverEndpoint::handle_packet_(const packet::PacketPtr& packet, core::nanoseconds_t current_time) { - status::StatusCode code = status::NoStatus; - - if ((code = parser_->parse(*packet, packet->buffer())) != status::StatusOK) { - roc_log(LogDebug, - "receiver endpoint: dropping bad packet: can't parse: status=%s", - status::code_to_str(code)); + if (!parser_->parse(*packet, packet->buffer())) { + roc_log(LogDebug, "receiver endpoint: dropping bad packet: can't parse"); return status::StatusOK; } - code = session_group_.route_packet(packet, current_time); + const status::StatusCode code = session_group_.route_packet(packet, current_time); if (code == status::StatusNoRoute) { roc_log(LogDebug, "receiver endpoint: dropping bad packet: can't route"); diff --git a/src/internal_modules/roc_pipeline/receiver_endpoint.h b/src/internal_modules/roc_pipeline/receiver_endpoint.h index 65e49f4b0..d997080cc 100644 --- a/src/internal_modules/roc_pipeline/receiver_endpoint.h +++ b/src/internal_modules/roc_pipeline/receiver_endpoint.h @@ -93,10 +93,10 @@ class ReceiverEndpoint : public core::RefCountedcname(); part_info.source_id = identity_->ssrc(); - if (rtcp_inbound_addr_.is_multicast()) { + if (rtcp_inbound_addr_.multicast()) { part_info.report_mode = rtcp::Report_ToAddress; part_info.report_address = rtcp_inbound_addr_; } else { diff --git a/src/internal_modules/roc_pipeline/receiver_session_group.h b/src/internal_modules/roc_pipeline/receiver_session_group.h index b53e31c20..946a5d367 100644 --- a/src/internal_modules/roc_pipeline/receiver_session_group.h +++ b/src/internal_modules/roc_pipeline/receiver_session_group.h @@ -72,7 +72,7 @@ class ReceiverSessionGroup : public core::NonCopyable<>, private rtcp::IParticip //! it's created separately using this method. On the other hand, //! transport sub-pipeline is per-session and is created automatically //! when a session is created within group. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode create_control_pipeline(ReceiverEndpoint* control_endpoint); //! Refresh pipeline according to current time. @@ -80,8 +80,9 @@ class ReceiverSessionGroup : public core::NonCopyable<>, private rtcp::IParticip //! Should be invoked before reading each frame. //! If there are no frames for a while, should be invoked no //! later than the deadline returned via @p next_deadline. - ROC_NODISCARD status::StatusCode refresh_sessions(core::nanoseconds_t current_time, - core::nanoseconds_t& next_deadline); + ROC_ATTR_NODISCARD status::StatusCode + refresh_sessions(core::nanoseconds_t current_time, + core::nanoseconds_t& next_deadline); //! Adjust session clock to match consumer clock. //! @remarks @@ -90,8 +91,8 @@ class ReceiverSessionGroup : public core::NonCopyable<>, private rtcp::IParticip void reclock_sessions(core::nanoseconds_t playback_time); //! Route packet to session. - ROC_NODISCARD status::StatusCode route_packet(const packet::PacketPtr& packet, - core::nanoseconds_t current_time); + ROC_ATTR_NODISCARD status::StatusCode route_packet(const packet::PacketPtr& packet, + core::nanoseconds_t current_time); //! Get number of sessions in group. size_t num_sessions() const; diff --git a/src/internal_modules/roc_pipeline/receiver_session_router.h b/src/internal_modules/roc_pipeline/receiver_session_router.h index 07ea59876..f93590b50 100644 --- a/src/internal_modules/roc_pipeline/receiver_session_router.h +++ b/src/internal_modules/roc_pipeline/receiver_session_router.h @@ -108,7 +108,7 @@ class ReceiverSessionRouter : public core::NonCopyable<> { //! Additional streams may be associated with same session via link_source() call. //! - @p source_addr defines source address which will be routed to the session. //! If other streams share the same source address, they will be routed to it. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode add_session(const core::SharedPtr& session, packet::stream_source_t source_id, const address::SocketAddr& source_addr); @@ -123,8 +123,8 @@ class ReceiverSessionRouter : public core::NonCopyable<> { //! Remembers what SSRCs are linked together by sharing the same CNAME. //! If/when one of the linked SSRCs is associated with a session using add_session(), //! all linked SSRCs become being routed to that session. - ROC_NODISCARD status::StatusCode link_source(packet::stream_source_t source_id, - const char* cname); + ROC_ATTR_NODISCARD status::StatusCode link_source(packet::stream_source_t source_id, + const char* cname); //! Unlink source id from session. //! @remarks diff --git a/src/internal_modules/roc_pipeline/receiver_slot.h b/src/internal_modules/roc_pipeline/receiver_slot.h index f148f8208..5fce96f2c 100644 --- a/src/internal_modules/roc_pipeline/receiver_slot.h +++ b/src/internal_modules/roc_pipeline/receiver_slot.h @@ -65,8 +65,8 @@ class ReceiverSlot : public core::RefCounted { //! Should be invoked before reading each frame. //! If there are no frames for a while, should be invoked no //! later than the deadline returned via @p next_deadline. - ROC_NODISCARD status::StatusCode refresh(core::nanoseconds_t current_time, - core::nanoseconds_t* next_deadline); + ROC_ATTR_NODISCARD status::StatusCode refresh(core::nanoseconds_t current_time, + core::nanoseconds_t* next_deadline); //! Get type (sink or source). virtual sndio::DeviceType type() const; @@ -98,10 +98,10 @@ class ReceiverSource : public sndio::ISource, public core::NonCopyable<> { virtual sndio::DeviceState state() const; //! Pause source. - virtual ROC_NODISCARD status::StatusCode pause(); + virtual ROC_ATTR_NODISCARD status::StatusCode pause(); //! Resume source. - virtual ROC_NODISCARD status::StatusCode resume(); + virtual ROC_ATTR_NODISCARD status::StatusCode resume(); //! Check if the source supports latency reports. virtual bool has_latency() const; @@ -113,7 +113,7 @@ class ReceiverSource : public sndio::ISource, public core::NonCopyable<> { virtual bool has_clock() const; //! Restart reading from beginning. - virtual ROC_NODISCARD status::StatusCode rewind(); + virtual ROC_ATTR_NODISCARD status::StatusCode rewind(); //! Adjust sessions clock to match consumer clock. //! @remarks @@ -121,12 +121,13 @@ class ReceiverSource : public sndio::ISource, public core::NonCopyable<> { virtual void reclock(core::nanoseconds_t playback_time); //! Read frame. - virtual ROC_NODISCARD status::StatusCode read(audio::Frame& frame, - packet::stream_timestamp_t duration, - audio::FrameReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode + read(audio::Frame& frame, + packet::stream_timestamp_t duration, + audio::FrameReadMode mode); //! Explicitly close the source. - virtual ROC_NODISCARD status::StatusCode close(); + virtual ROC_ATTR_NODISCARD status::StatusCode close(); //! Destroy object and return memory to arena. virtual void dispose(); diff --git a/src/internal_modules/roc_pipeline/sender_endpoint.cpp b/src/internal_modules/roc_pipeline/sender_endpoint.cpp index b8f7556b5..cf8748a69 100644 --- a/src/internal_modules/roc_pipeline/sender_endpoint.cpp +++ b/src/internal_modules/roc_pipeline/sender_endpoint.cpp @@ -210,15 +210,12 @@ status::StatusCode SenderEndpoint::pull_packets(core::nanoseconds_t current_time status::StatusCode SenderEndpoint::handle_packet_(const packet::PacketPtr& packet, core::nanoseconds_t current_time) { - status::StatusCode code = status::NoStatus; - - if ((code = parser_->parse(*packet, packet->buffer())) != status::StatusOK) { - roc_log(LogDebug, "sender endpoint: dropping bad packet: can't parse: status=%s", - status::code_to_str(code)); + if (!parser_->parse(*packet, packet->buffer())) { + roc_log(LogDebug, "sender endpoint: dropping bad packet: can't parse"); return status::StatusOK; } - code = sender_session_.route_packet(packet, current_time); + const status::StatusCode code = sender_session_.route_packet(packet, current_time); if (code == status::StatusNoRoute) { roc_log(LogDebug, "sender endpoint: dropping bad packet: can't route"); diff --git a/src/internal_modules/roc_pipeline/sender_endpoint.h b/src/internal_modules/roc_pipeline/sender_endpoint.h index 1b01cb0bd..751a7820b 100644 --- a/src/internal_modules/roc_pipeline/sender_endpoint.h +++ b/src/internal_modules/roc_pipeline/sender_endpoint.h @@ -91,10 +91,10 @@ class SenderEndpoint : public core::NonCopyable<>, private packet::IWriter { //! Packets are written to inbound_writer() from network thread. //! They don't appear in pipeline immediately. Instead, pipeline thread //! should periodically call pull_packets() to make them available. - ROC_NODISCARD status::StatusCode pull_packets(core::nanoseconds_t current_time); + ROC_ATTR_NODISCARD status::StatusCode pull_packets(core::nanoseconds_t current_time); private: - virtual ROC_NODISCARD status::StatusCode write(const packet::PacketPtr& packet); + virtual ROC_ATTR_NODISCARD status::StatusCode write(const packet::PacketPtr& packet); status::StatusCode handle_packet_(const packet::PacketPtr& packet, core::nanoseconds_t current_time); diff --git a/src/internal_modules/roc_pipeline/sender_loop.h b/src/internal_modules/roc_pipeline/sender_loop.h index 7f6f75f13..c8289d9bd 100644 --- a/src/internal_modules/roc_pipeline/sender_loop.h +++ b/src/internal_modules/roc_pipeline/sender_loop.h @@ -154,7 +154,7 @@ class SenderLoop : public PipelineLoop, private sndio::ISink { virtual core::nanoseconds_t latency() const; virtual bool has_clock() const; virtual status::StatusCode write(audio::Frame& frame); - virtual ROC_NODISCARD status::StatusCode flush(); + virtual ROC_ATTR_NODISCARD status::StatusCode flush(); virtual status::StatusCode close(); virtual void dispose(); diff --git a/src/internal_modules/roc_pipeline/sender_session.cpp b/src/internal_modules/roc_pipeline/sender_session.cpp index f649c4b39..51a5d3c9f 100644 --- a/src/internal_modules/roc_pipeline/sender_session.cpp +++ b/src/internal_modules/roc_pipeline/sender_session.cpp @@ -425,7 +425,7 @@ void SenderSession::start_feedback_monitor_() { return; } - if (rtcp_outbound_addr_.is_multicast()) { + if (rtcp_outbound_addr_.multicast()) { // Control endpoint uses multicast, so there are multiple receivers for // a sender session. We don't support feedback monitoring in this mode. return; diff --git a/src/internal_modules/roc_pipeline/sender_session.h b/src/internal_modules/roc_pipeline/sender_session.h index 2aff79c07..ba736ff5e 100644 --- a/src/internal_modules/roc_pipeline/sender_session.h +++ b/src/internal_modules/roc_pipeline/sender_session.h @@ -68,12 +68,12 @@ class SenderSession : public core::NonCopyable<>, status::StatusCode init_status() const; //! Create transport sub-pipeline. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode create_transport_pipeline(SenderEndpoint* source_endpoint, SenderEndpoint* repair_endpoint); //! Create control sub-pipeline. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode create_control_pipeline(SenderEndpoint* control_endpoint); //! Get frame writer. @@ -88,16 +88,16 @@ class SenderSession : public core::NonCopyable<>, //! Should be invoked before reading each frame. //! If there are no frames for a while, should be invoked no //! later than the deadline returned via @p next_deadline. - ROC_NODISCARD status::StatusCode refresh(core::nanoseconds_t current_time, - core::nanoseconds_t& next_deadline); + ROC_ATTR_NODISCARD status::StatusCode refresh(core::nanoseconds_t current_time, + core::nanoseconds_t& next_deadline); //! Route a packet to the session. //! @remarks //! This way feedback packets from receiver reach sender pipeline. //! Packets are stored inside internal pipeline queues, and then fetched //! when frame are passed from frame_writer(). - ROC_NODISCARD status::StatusCode route_packet(const packet::PacketPtr& packet, - core::nanoseconds_t current_time); + ROC_ATTR_NODISCARD status::StatusCode route_packet(const packet::PacketPtr& packet, + core::nanoseconds_t current_time); //! Get slot metrics. //! @remarks diff --git a/src/internal_modules/roc_pipeline/sender_sink.h b/src/internal_modules/roc_pipeline/sender_sink.h index e59a0ad2a..37290ad4f 100644 --- a/src/internal_modules/roc_pipeline/sender_sink.h +++ b/src/internal_modules/roc_pipeline/sender_sink.h @@ -72,8 +72,8 @@ class SenderSink : public sndio::ISink, public core::NonCopyable<> { //! Should be invoked before reading each frame. //! If there are no frames for a while, should be invoked no //! later than the deadline returned via @p next_deadline. - ROC_NODISCARD status::StatusCode refresh(core::nanoseconds_t current_time, - core::nanoseconds_t* next_deadline); + ROC_ATTR_NODISCARD status::StatusCode refresh(core::nanoseconds_t current_time, + core::nanoseconds_t* next_deadline); //! Get type (sink or source). virtual sndio::DeviceType type() const; @@ -97,10 +97,10 @@ class SenderSink : public sndio::ISink, public core::NonCopyable<> { virtual sndio::DeviceState state() const; //! Pause sink. - virtual ROC_NODISCARD status::StatusCode pause(); + virtual ROC_ATTR_NODISCARD status::StatusCode pause(); //! Resume sink. - virtual ROC_NODISCARD status::StatusCode resume(); + virtual ROC_ATTR_NODISCARD status::StatusCode resume(); //! Check if the sink supports latency reports. virtual bool has_latency() const; @@ -112,13 +112,13 @@ class SenderSink : public sndio::ISink, public core::NonCopyable<> { virtual bool has_clock() const; //! Write frame. - virtual ROC_NODISCARD status::StatusCode write(audio::Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(audio::Frame& frame); //! Flush buffered data, if any. - virtual ROC_NODISCARD status::StatusCode flush(); + virtual ROC_ATTR_NODISCARD status::StatusCode flush(); //! Explicitly close the sink. - virtual ROC_NODISCARD status::StatusCode close(); + virtual ROC_ATTR_NODISCARD status::StatusCode close(); //! Destroy object and return memory to arena. virtual void dispose(); diff --git a/src/internal_modules/roc_pipeline/sender_slot.h b/src/internal_modules/roc_pipeline/sender_slot.h index 75693857d..608c65e2e 100644 --- a/src/internal_modules/roc_pipeline/sender_slot.h +++ b/src/internal_modules/roc_pipeline/sender_slot.h @@ -68,8 +68,8 @@ class SenderSlot : public core::RefCounted, //! Should be invoked before reading each frame. //! If there are no frames for a while, should be invoked no //! later than the deadline returned via @p next_deadline. - ROC_NODISCARD status::StatusCode refresh(core::nanoseconds_t current_time, - core::nanoseconds_t& next_deadline); + ROC_ATTR_NODISCARD status::StatusCode refresh(core::nanoseconds_t current_time, + core::nanoseconds_t& next_deadline); //! Get metrics for slot and its participants. void get_metrics(SenderSlotMetrics& slot_metrics, diff --git a/src/internal_modules/roc_pipeline/state_tracker.cpp b/src/internal_modules/roc_pipeline/state_tracker.cpp index bc2b6ef6f..9f0032638 100644 --- a/src/internal_modules/roc_pipeline/state_tracker.cpp +++ b/src/internal_modules/roc_pipeline/state_tracker.cpp @@ -7,15 +7,73 @@ */ #include "roc_pipeline/state_tracker.h" +#include "roc_core/log.h" #include "roc_core/panic.h" namespace roc { namespace pipeline { StateTracker::StateTracker() - : halt_state_(-1) + : sem_(0) + , halt_state_(-1) , active_sessions_(0) - , pending_packets_(0) { + , pending_packets_(0) + , sem_is_occupied_(0) + , waiting_mask_(0) + , mutex_() + , waiting_con_(mutex_) { +} + +// StateTracker::~StateTracker() { +// mutex_.unlock(); +// } + +// This method should block until the state becomes any of the states specified by the +// mask, or deadline expires. E.g. if mask is ACTIVE | PAUSED, it should block until state +// becomes either ACTIVE or PAUSED. (Currently only two states are used, but later more +// states will be needed). Deadline should be an absolute timestamp. + +// Questions: +// - When should the function return true vs false +bool StateTracker::wait_state(unsigned int state_mask, core::nanoseconds_t deadline) { + waiting_mask_ = state_mask; + for (;;) { + // If no state is specified in state_mask, return immediately + if (state_mask == 0) { + return true; + } + + if (static_cast(get_state()) & state_mask) { + waiting_mask_ = 0; + return true; + } + + if (deadline >= 0 && deadline <= core::timestamp(core::ClockMonotonic)) { + waiting_mask_ = 0; + return false; + } + + if (sem_is_occupied_.compare_exchange(0, 1)) { + if (deadline >= 0) { + (void)sem_.timed_wait(deadline); + + } else { + sem_.wait(); + } + + sem_is_occupied_ = 0; + waiting_con_.broadcast(); + + } else { + core::Mutex::Lock lock(mutex_); + + if (deadline >= 0) { + (void)waiting_con_.timed_wait(deadline); + } else { + waiting_con_.wait(); + } + } + } } sndio::DeviceState StateTracker::get_state() const { @@ -65,22 +123,50 @@ size_t StateTracker::num_sessions() const { } void StateTracker::register_session() { - active_sessions_++; + if (active_sessions_++ == 0) { + signal_state_change(); + } } void StateTracker::unregister_session() { - if (--active_sessions_ < 0) { + int prev_sessions = active_sessions_--; + if (prev_sessions == 0) { roc_panic("state tracker: unpaired register/unregister session"); + } else if (prev_sessions == 1 && pending_packets_ == 0) { + signal_state_change(); } + + // if (--active_sessions_ < 0) { + // roc_panic("state tracker: unpaired register/unregister session"); + // } } void StateTracker::register_packet() { - pending_packets_++; + if (pending_packets_++ == 0 && active_sessions_ == 0) { + signal_state_change(); + } } void StateTracker::unregister_packet() { - if (--pending_packets_ < 0) { + int prev_packets = pending_packets_--; + if (prev_packets == 0) { roc_panic("state tracker: unpaired register/unregister packet"); + } else if (prev_packets == 1 && active_sessions_ == 0) { + signal_state_change(); + } + + // if (--pending_packets_ < 0) { + // roc_panic("state tracker: unpaired register/unregister packet"); + // } +} + +void StateTracker::signal_state_change() { + // if (waiting_mask_ != 0 && (static_cast(get_state()) & waiting_mask_)) { + // sem_.post(); + // } + if (sem_is_occupied_) { + roc_log(LogDebug, "signaling"); + sem_.post(); } } diff --git a/src/internal_modules/roc_pipeline/state_tracker.h b/src/internal_modules/roc_pipeline/state_tracker.h index 981ed0274..fd99fd79c 100644 --- a/src/internal_modules/roc_pipeline/state_tracker.h +++ b/src/internal_modules/roc_pipeline/state_tracker.h @@ -13,9 +13,13 @@ #define ROC_PIPELINE_STATE_TRACKER_H_ #include "roc_core/atomic.h" +#include "roc_core/cond.h" +#include "roc_core/mutex.h" #include "roc_core/noncopyable.h" +#include "roc_core/semaphore.h" #include "roc_core/stddefs.h" -#include "roc_sndio/device_defs.h" +#include "roc_core/time.h" +#include "roc_sndio/device_state.h" namespace roc { namespace pipeline { @@ -32,6 +36,9 @@ class StateTracker : public core::NonCopyable<> { //! Initialize all counters to zero. StateTracker(); + //! Block until state becomes any of the ones specified by state_mask. + bool wait_state(unsigned state_mask, core::nanoseconds_t deadline); + //! Compute current state. sndio::DeviceState get_state() const; @@ -63,9 +70,16 @@ class StateTracker : public core::NonCopyable<> { void unregister_packet(); private: + core::Semaphore sem_; core::Atomic halt_state_; core::Atomic active_sessions_; core::Atomic pending_packets_; + core::Atomic sem_is_occupied_; + core::Atomic waiting_mask_; + core::Mutex mutex_; + core::Cond waiting_con_; + + void signal_state_change(); }; } // namespace pipeline diff --git a/src/internal_modules/roc_pipeline/transcoder_sink.h b/src/internal_modules/roc_pipeline/transcoder_sink.h index 26632356b..ffe991cc9 100644 --- a/src/internal_modules/roc_pipeline/transcoder_sink.h +++ b/src/internal_modules/roc_pipeline/transcoder_sink.h @@ -70,13 +70,13 @@ class TranscoderSink : public sndio::ISink, public core::NonCopyable<> { virtual bool has_clock() const; //! Write frame. - virtual ROC_NODISCARD status::StatusCode write(audio::Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(audio::Frame& frame); //! Flush buffered data, if any. - virtual ROC_NODISCARD status::StatusCode flush(); + virtual ROC_ATTR_NODISCARD status::StatusCode flush(); //! Explicitly close the sink. - virtual ROC_NODISCARD status::StatusCode close(); + virtual ROC_ATTR_NODISCARD status::StatusCode close(); //! Destroy object and return memory to arena. virtual void dispose(); diff --git a/src/internal_modules/roc_pipeline/transcoder_source.h b/src/internal_modules/roc_pipeline/transcoder_source.h index 39aed8644..cd62c1545 100644 --- a/src/internal_modules/roc_pipeline/transcoder_source.h +++ b/src/internal_modules/roc_pipeline/transcoder_source.h @@ -66,10 +66,10 @@ class TranscoderSource : public sndio::ISource, public core::NonCopyable<> { virtual sndio::DeviceState state() const; //! Pause source. - virtual ROC_NODISCARD status::StatusCode pause(); + virtual ROC_ATTR_NODISCARD status::StatusCode pause(); //! Resume source. - virtual ROC_NODISCARD status::StatusCode resume(); + virtual ROC_ATTR_NODISCARD status::StatusCode resume(); //! Check if the source supports latency reports. virtual bool has_latency() const; @@ -81,18 +81,19 @@ class TranscoderSource : public sndio::ISource, public core::NonCopyable<> { virtual bool has_clock() const; //! Restart reading from beginning. - virtual ROC_NODISCARD status::StatusCode rewind(); + virtual ROC_ATTR_NODISCARD status::StatusCode rewind(); //! Adjust sessions clock to match consumer clock. virtual void reclock(core::nanoseconds_t playback_time); //! Read frame. - virtual ROC_NODISCARD status::StatusCode read(audio::Frame& frame, - packet::stream_timestamp_t duration, - audio::FrameReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode + read(audio::Frame& frame, + packet::stream_timestamp_t duration, + audio::FrameReadMode mode); //! Explicitly close the source. - virtual ROC_NODISCARD status::StatusCode close(); + virtual ROC_ATTR_NODISCARD status::StatusCode close(); //! Destroy object and return memory to arena. virtual void dispose(); diff --git a/src/internal_modules/roc_rtcp/communicator.cpp b/src/internal_modules/roc_rtcp/communicator.cpp index 864836414..70b9a48d7 100644 --- a/src/internal_modules/roc_rtcp/communicator.cpp +++ b/src/internal_modules/roc_rtcp/communicator.cpp @@ -576,10 +576,9 @@ status::StatusCode Communicator::generate_packet_(PacketType packet_type, packet_buffer.reslice(0, 0); // Prepare packet to be able to hold our RTCP packet data - status = packet_composer_.prepare(*packet, packet_buffer, payload_buffer.size()); - if (status != status::StatusOK) { + if (!packet_composer_.prepare(*packet, packet_buffer, payload_buffer.size())) { roc_log(LogError, "rtcp communicator: can't prepare packet"); - return status; + return status::StatusNoMem; } packet->add_flags(packet::Packet::FlagPrepared); diff --git a/src/internal_modules/roc_rtcp/communicator.h b/src/internal_modules/roc_rtcp/communicator.h index 0d86d2551..4b4e4eb39 100644 --- a/src/internal_modules/roc_rtcp/communicator.h +++ b/src/internal_modules/roc_rtcp/communicator.h @@ -74,8 +74,8 @@ class Communicator : public core::NonCopyable<> { //! Parse and process incoming packet. //! Invokes IParticipant methods during processing. - ROC_NODISCARD status::StatusCode process_packet(const packet::PacketPtr& packet, - core::nanoseconds_t current_time); + ROC_ATTR_NODISCARD status::StatusCode + process_packet(const packet::PacketPtr& packet, core::nanoseconds_t current_time); //! When we should generate packets next time. //! Returns absolute time. @@ -86,13 +86,15 @@ class Communicator : public core::NonCopyable<> { //! Should be called according to generation_deadline(). //! @p current_time is current time in nanoseconds since Unix epoch. //! Invokes IParticipant methods during generation. - ROC_NODISCARD status::StatusCode generate_reports(core::nanoseconds_t current_time); + ROC_ATTR_NODISCARD status::StatusCode + generate_reports(core::nanoseconds_t current_time); //! Generate and send goodbye packet(s). //! Should be called before termination sender session. //! @p current_time is current time in nanoseconds since Unix epoch. //! Invokes IParticipant methods during generation. - ROC_NODISCARD status::StatusCode generate_goodbye(core::nanoseconds_t current_time); + ROC_ATTR_NODISCARD status::StatusCode + generate_goodbye(core::nanoseconds_t current_time); private: enum PacketType { PacketType_Reports, PacketType_Goodbye }; diff --git a/src/internal_modules/roc_rtcp/composer.cpp b/src/internal_modules/roc_rtcp/composer.cpp index 951913cbb..eb53c0d85 100644 --- a/src/internal_modules/roc_rtcp/composer.cpp +++ b/src/internal_modules/roc_rtcp/composer.cpp @@ -18,13 +18,13 @@ Composer::Composer(core::IArena& arena) : IComposer(arena) { } -ROC_NODISCARD status::StatusCode Composer::init_status() const { +status::StatusCode Composer::init_status() const { return status::StatusOK; } -ROC_NODISCARD status::StatusCode Composer::align(core::Slice& buffer, - size_t header_size, - size_t payload_alignment) { +bool Composer::align(core::Slice& buffer, + size_t header_size, + size_t payload_alignment) { if ((unsigned long)buffer.data() % payload_alignment != 0) { roc_panic("rtcp composer: unexpected non-aligned buffer"); } @@ -35,16 +35,16 @@ ROC_NODISCARD status::StatusCode Composer::align(core::Slice& buffer, roc_log(LogDebug, "rtcp composer: not enough space for alignment: padding=%lu cap=%lu", (unsigned long)padding, (unsigned long)buffer.capacity()); - return status::StatusBadBuffer; + return false; } buffer.reslice(padding, padding); - return status::StatusOK; + return true; } -ROC_NODISCARD status::StatusCode Composer::prepare(packet::Packet& packet, - core::Slice& buffer, - size_t payload_size) { +bool Composer::prepare(packet::Packet& packet, + core::Slice& buffer, + size_t payload_size) { buffer.reslice(0, payload_size); packet.add_flags(packet::Packet::FlagControl); @@ -52,33 +52,34 @@ ROC_NODISCARD status::StatusCode Composer::prepare(packet::Packet& packet, packet.rtcp()->payload = buffer; - return status::StatusOK; + return true; } -ROC_NODISCARD status::StatusCode Composer::pad(packet::Packet& packet, - size_t padding_size) { +bool Composer::pad(packet::Packet& packet, size_t padding_size) { // not supported (void)packet; (void)padding_size; - return status::StatusBadOperation; + return false; } -ROC_NODISCARD status::StatusCode Composer::compose(packet::Packet& packet) { +bool Composer::compose(packet::Packet& packet) { if (!packet.rtcp()) { roc_panic("rtcp composer: unexpected non-rctp packet"); } if (!packet.rtcp()->payload) { - roc_panic("rtcp composer: unexpected null data"); + roc_log(LogError, "rtcp composer: unexpected null data"); + return false; } if (packet.rtcp()->payload.size() == 0) { - roc_panic("rtcp composer: unexpected zero data"); + roc_log(LogError, "rtcp composer: unexpected zero data"); + return false; } - return status::StatusOK; + return true; } } // namespace rtcp diff --git a/src/internal_modules/roc_rtcp/composer.h b/src/internal_modules/roc_rtcp/composer.h index 60c1c514f..8af74e5e7 100644 --- a/src/internal_modules/roc_rtcp/composer.h +++ b/src/internal_modules/roc_rtcp/composer.h @@ -30,22 +30,21 @@ class Composer : public packet::IComposer, public core::NonCopyable<> { explicit Composer(core::IArena& arena); //! Check if the object was successfully constructed. - ROC_NODISCARD virtual status::StatusCode init_status() const; + virtual status::StatusCode init_status() const; //! Adjust buffer to align payload. - ROC_NODISCARD virtual status::StatusCode + virtual bool align(core::Slice& buffer, size_t header_size, size_t payload_alignment); //! Prepare buffer for composing a packet. - ROC_NODISCARD virtual status::StatusCode + virtual bool prepare(packet::Packet& packet, core::Slice& buffer, size_t payload_size); //! Pad packet. - ROC_NODISCARD virtual status::StatusCode pad(packet::Packet& packet, - size_t padding_size); + virtual bool pad(packet::Packet& packet, size_t padding_size); //! Compose packet to buffer. - ROC_NODISCARD virtual status::StatusCode compose(packet::Packet& packet); + virtual bool compose(packet::Packet& packet); }; } // namespace rtcp diff --git a/src/internal_modules/roc_rtcp/headers.h b/src/internal_modules/roc_rtcp/headers.h index a3d3bb481..62348da76 100644 --- a/src/internal_modules/roc_rtcp/headers.h +++ b/src/internal_modules/roc_rtcp/headers.h @@ -123,7 +123,7 @@ enum PacketType { //! |V=2|P| RC | PT | length | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class PacketHeader { +ROC_ATTR_PACKED_BEGIN class PacketHeader { private: enum { //! @name RTCP protocol version. @@ -235,7 +235,7 @@ ROC_PACKED_BEGIN class PacketHeader { void set_len_bytes(const size_t len) { set_len_words(size_t_2_rtcp_length(len)); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! 64-bit NTP timestamp. //! @@ -250,7 +250,7 @@ ROC_PACKED_BEGIN class PacketHeader { //! @endcode //! //! From RFC 3550. -ROC_PACKED_BEGIN class NtpTimestamp64 { +ROC_ATTR_PACKED_BEGIN class NtpTimestamp64 { private: uint32_t high_; uint32_t low_; @@ -271,7 +271,7 @@ ROC_PACKED_BEGIN class NtpTimestamp64 { high_ = core::hton32u((uint32_t)(t >> 32)); low_ = core::hton32u((uint32_t)t); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! 32-bit NTP absolute time (stored as middle 32 bits of 64-bit timestamp). //! @@ -284,7 +284,7 @@ ROC_PACKED_BEGIN class NtpTimestamp64 { //! @endcode //! //! From RFC 3550. -ROC_PACKED_BEGIN class NtpTimestamp32 { +ROC_ATTR_PACKED_BEGIN class NtpTimestamp32 { private: uint32_t mid_; @@ -304,7 +304,7 @@ ROC_PACKED_BEGIN class NtpTimestamp32 { void set_value(const packet::ntp_timestamp_t t) { mid_ = core::hton32u(t >> 16); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! Reception report block. //! @@ -330,7 +330,7 @@ ROC_PACKED_BEGIN class NtpTimestamp32 { //! | delay since last SR (DLSR) | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class ReceptionReportBlock { +ROC_ATTR_PACKED_BEGIN class ReceptionReportBlock { private: enum { //! @name Fraction lost since last SR/RR. @@ -488,7 +488,7 @@ ROC_PACKED_BEGIN class ReceptionReportBlock { void set_delay_last_sr(const packet::ntp_timestamp_t x) { delay_last_sr_.set_value(ntp_clamp_32(x, MaxDelay)); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! Receiver Report RTCP packet (RR). //! @@ -521,7 +521,7 @@ ROC_PACKED_BEGIN class ReceptionReportBlock { //! | profile-specific extensions | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class ReceiverReportPacket { +ROC_ATTR_PACKED_BEGIN class ReceiverReportPacket { private: PacketHeader header_; @@ -575,7 +575,7 @@ ROC_PACKED_BEGIN class ReceiverReportPacket { return get_block_by_index(this, i, header().counter(), "rtcp rr"); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! Sender Report RTCP packet (SR). //! @@ -618,7 +618,7 @@ ROC_PACKED_BEGIN class ReceiverReportPacket { //! | profile-specific extensions | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class SenderReportPacket { +ROC_ATTR_PACKED_BEGIN class SenderReportPacket { private: PacketHeader header_; @@ -719,7 +719,7 @@ ROC_PACKED_BEGIN class SenderReportPacket { return get_block_by_index(this, i, header().counter(), "rtcp sr"); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! SDES item type. enum SdesItemType { @@ -747,7 +747,7 @@ enum SdesItemType { //! | SSRC | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class SdesChunkHeader { +ROC_ATTR_PACKED_BEGIN class SdesChunkHeader { private: uint32_t ssrc_; @@ -770,7 +770,7 @@ ROC_PACKED_BEGIN class SdesChunkHeader { void set_ssrc(const packet::stream_source_t s) { ssrc_ = core::hton32u(s); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! SDES item header. //! @@ -785,7 +785,7 @@ ROC_PACKED_BEGIN class SdesChunkHeader { //! | Type | Length | Text in UTF-8 ... //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class SdesItemHeader { +ROC_ATTR_PACKED_BEGIN class SdesItemHeader { private: uint8_t type_; uint8_t len_; @@ -832,7 +832,7 @@ ROC_PACKED_BEGIN class SdesItemHeader { uint8_t* text() { return (uint8_t*)this + sizeof(*this); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! Source Description RTCP packet (SDES). //! @@ -861,7 +861,7 @@ ROC_PACKED_BEGIN class SdesItemHeader { //! : ... : //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ //! @endcode -ROC_PACKED_BEGIN class SdesPacket { +ROC_ATTR_PACKED_BEGIN class SdesPacket { private: PacketHeader header_; @@ -884,7 +884,7 @@ ROC_PACKED_BEGIN class SdesPacket { PacketHeader& header() { return header_; } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! BYE source header. //! @@ -899,7 +899,7 @@ ROC_PACKED_BEGIN class SdesPacket { //! | SSRC | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class ByeSourceHeader { +ROC_ATTR_PACKED_BEGIN class ByeSourceHeader { private: uint32_t ssrc_; @@ -922,7 +922,7 @@ ROC_PACKED_BEGIN class ByeSourceHeader { void set_ssrc(const packet::stream_source_t s) { ssrc_ = core::hton32u(s); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! BYE reason header. //! @@ -937,7 +937,7 @@ ROC_PACKED_BEGIN class ByeSourceHeader { //! | length | reason for leaving ... //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class ByeReasonHeader { +ROC_ATTR_PACKED_BEGIN class ByeReasonHeader { private: uint8_t len_; @@ -973,7 +973,7 @@ ROC_PACKED_BEGIN class ByeReasonHeader { uint8_t* text() { return (uint8_t*)this + sizeof(*this); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! Goodbye RTCP packet (BYE). //! @@ -992,7 +992,7 @@ ROC_PACKED_BEGIN class ByeReasonHeader { //! (opt) | length | reason for leaving ... //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class ByePacket { +ROC_ATTR_PACKED_BEGIN class ByePacket { private: PacketHeader header_; @@ -1015,7 +1015,7 @@ ROC_PACKED_BEGIN class ByePacket { PacketHeader& header() { return header_; } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! RTCP Extended Report Packet. //! @@ -1032,7 +1032,7 @@ ROC_PACKED_BEGIN class ByePacket { //! : report blocks : //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class XrPacket { +ROC_ATTR_PACKED_BEGIN class XrPacket { private: PacketHeader header_; @@ -1069,7 +1069,7 @@ ROC_PACKED_BEGIN class XrPacket { void set_ssrc(const packet::stream_source_t ssrc) { ssrc_ = core::hton32u(ssrc); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! XR Block Type. enum XrBlockType { @@ -1097,7 +1097,7 @@ enum XrBlockType { //! : type-specific block contents : //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class XrBlockHeader { +ROC_ATTR_PACKED_BEGIN class XrBlockHeader { private: uint8_t block_type_; uint8_t type_specific_; @@ -1154,7 +1154,7 @@ ROC_PACKED_BEGIN class XrBlockHeader { void set_len_bytes(const size_t len) { set_len_words(size_t_2_rtcp_length(len)); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! XR Receiver Reference Time Report block. //! @@ -1171,7 +1171,7 @@ ROC_PACKED_BEGIN class XrBlockHeader { //! | NTP timestamp, least significant word | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class XrRrtrBlock { +ROC_ATTR_PACKED_BEGIN class XrRrtrBlock { private: XrBlockHeader header_; @@ -1208,7 +1208,7 @@ ROC_PACKED_BEGIN class XrRrtrBlock { void set_ntp_timestamp(const packet::ntp_timestamp_t t) { ntp_timestamp_.set_value(t); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! XR DLRR Report sub-block. //! @@ -1225,7 +1225,7 @@ ROC_PACKED_BEGIN class XrRrtrBlock { //! | delay since last RR (DLRR) | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class XrDlrrSubblock { +ROC_ATTR_PACKED_BEGIN class XrDlrrSubblock { private: uint32_t ssrc_; NtpTimestamp32 last_rr_; @@ -1274,7 +1274,7 @@ ROC_PACKED_BEGIN class XrDlrrSubblock { void set_delay_last_rr(const packet::ntp_timestamp_t x) { delay_last_rr_.set_value(ntp_clamp_32(x, MaxDelay)); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! XR DLRR Report block. //! @@ -1300,7 +1300,7 @@ ROC_PACKED_BEGIN class XrDlrrSubblock { //! : ... : 2 //! +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ //! @endcode -ROC_PACKED_BEGIN class XrDlrrBlock { +ROC_ATTR_PACKED_BEGIN class XrDlrrBlock { private: XrBlockHeader header_; @@ -1340,7 +1340,7 @@ ROC_PACKED_BEGIN class XrDlrrBlock { return get_block_by_index(this, i, num_subblocks(), "rtcp xr_dlrr"); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! XR Measurement Info Report Block. //! @@ -1370,7 +1370,7 @@ ROC_PACKED_BEGIN class XrDlrrBlock { //! | Measurement Duration (Cumulative) - Fraction (bit 0-31) | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class XrMeasurementInfoBlock { +ROC_ATTR_PACKED_BEGIN class XrMeasurementInfoBlock { private: XrBlockHeader header_; @@ -1512,7 +1512,7 @@ enum MetricFlag { //! | End System Delay - Fraction (bit 0-31) | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class XrDelayMetricsBlock { +ROC_ATTR_PACKED_BEGIN class XrDelayMetricsBlock { private: enum { MetricFlag_shift = 6, @@ -1637,7 +1637,7 @@ ROC_PACKED_BEGIN class XrDelayMetricsBlock { void set_e2e_latency(const packet::ntp_timestamp_t t) { e2e_latency_.set_value(ntp_clamp_64(t, MetricUnavail_64 - 1)); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! XR Queue Metrics Block. //! @@ -1665,7 +1665,7 @@ ROC_PACKED_BEGIN class XrDelayMetricsBlock { //! | Network Incoming Queue Stalling | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class XrQueueMetricsBlock { +ROC_ATTR_PACKED_BEGIN class XrQueueMetricsBlock { private: enum { MetricFlag_shift = 6, @@ -1753,7 +1753,7 @@ ROC_PACKED_BEGIN class XrQueueMetricsBlock { void set_niq_stalling(const packet::ntp_timestamp_t t) { niq_stalling_.set_value(ntp_clamp_32(t, MetricUnavail_32 - 1)); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; } // namespace header } // namespace rtcp diff --git a/src/internal_modules/roc_rtcp/iparticipant.h b/src/internal_modules/roc_rtcp/iparticipant.h index d3585364a..393ac04c6 100644 --- a/src/internal_modules/roc_rtcp/iparticipant.h +++ b/src/internal_modules/roc_rtcp/iparticipant.h @@ -75,7 +75,7 @@ class IParticipant { //! @p recv_source_id identifies remote receiver which sent report. //! In case of multicast sessions, one sending stream may have //! multiple receivers. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode notify_send_stream(packet::stream_source_t recv_source_id, const RecvReport& recv_report) { return status::StatusOK; @@ -102,7 +102,7 @@ class IParticipant { //! @p send_source_id identifies remote sender which sent report. //! If there are multiple receiving streams, each one will be notified //! with corresponding report. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode notify_recv_stream(packet::stream_source_t send_source_id, const SendReport& send_report) { return status::StatusOK; diff --git a/src/internal_modules/roc_rtcp/parser.cpp b/src/internal_modules/roc_rtcp/parser.cpp index 972b81b84..94c0e4cdb 100644 --- a/src/internal_modules/roc_rtcp/parser.cpp +++ b/src/internal_modules/roc_rtcp/parser.cpp @@ -20,8 +20,7 @@ status::StatusCode Parser::init_status() const { return status::StatusOK; } -status::StatusCode Parser::parse(packet::Packet& packet, - const core::Slice& buffer) { +bool Parser::parse(packet::Packet& packet, const core::Slice& buffer) { if (!buffer) { roc_panic("rtcp parser: buffer is null"); } @@ -31,7 +30,7 @@ status::StatusCode Parser::parse(packet::Packet& packet, packet.rtcp()->payload = buffer; - return status::StatusOK; + return true; } } // namespace rtcp diff --git a/src/internal_modules/roc_rtcp/parser.h b/src/internal_modules/roc_rtcp/parser.h index 8d3b5aff0..81e4f9da8 100644 --- a/src/internal_modules/roc_rtcp/parser.h +++ b/src/internal_modules/roc_rtcp/parser.h @@ -33,8 +33,7 @@ class Parser : public packet::IParser, public core::NonCopyable<> { virtual status::StatusCode init_status() const; //! Parse packet from buffer. - virtual ROC_NODISCARD status::StatusCode parse(packet::Packet& packet, - const core::Slice& buffer); + virtual bool parse(packet::Packet& packet, const core::Slice& buffer); }; } // namespace rtcp diff --git a/src/internal_modules/roc_rtcp/reporter.h b/src/internal_modules/roc_rtcp/reporter.h index bce290ea3..d03165f59 100644 --- a/src/internal_modules/roc_rtcp/reporter.h +++ b/src/internal_modules/roc_rtcp/reporter.h @@ -113,7 +113,7 @@ class Reporter : public core::NonCopyable<> { //! Begin report processing. //! Invoked before process_xxx() functions. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode begin_processing(const address::SocketAddr& report_addr, core::nanoseconds_t report_time); @@ -151,7 +151,7 @@ class Reporter : public core::NonCopyable<> { //! End report processing. //! Invoked after process_xxx() functions. - ROC_NODISCARD status::StatusCode end_processing(); + ROC_ATTR_NODISCARD status::StatusCode end_processing(); //! @} @@ -160,7 +160,8 @@ class Reporter : public core::NonCopyable<> { //! Begin report generation. //! Invoked before genrate_xxx() functions. - ROC_NODISCARD status::StatusCode begin_generation(core::nanoseconds_t report_time); + ROC_ATTR_NODISCARD status::StatusCode + begin_generation(core::nanoseconds_t report_time); //! Get number of destination addresses to which to send reports. size_t num_dest_addresses() const; @@ -235,7 +236,7 @@ class Reporter : public core::NonCopyable<> { //! End report generation. //! Invoked after generate_xxx() functions. - ROC_NODISCARD status::StatusCode end_generation(); + ROC_ATTR_NODISCARD status::StatusCode end_generation(); //! @} diff --git a/src/internal_modules/roc_rtp/composer.cpp b/src/internal_modules/roc_rtp/composer.cpp index 017ff2060..4ab52cc96 100644 --- a/src/internal_modules/roc_rtp/composer.cpp +++ b/src/internal_modules/roc_rtp/composer.cpp @@ -20,13 +20,13 @@ Composer::Composer(packet::IComposer* inner_composer, core::IArena& arena) , inner_composer_(inner_composer) { } -ROC_NODISCARD status::StatusCode Composer::init_status() const { +status::StatusCode Composer::init_status() const { return status::StatusOK; } -ROC_NODISCARD status::StatusCode Composer::align(core::Slice& buffer, - size_t header_size, - size_t payload_alignment) { +bool Composer::align(core::Slice& buffer, + size_t header_size, + size_t payload_alignment) { if ((unsigned long)buffer.data() % payload_alignment != 0) { roc_panic("rtp composer: unexpected non-aligned buffer"); } @@ -40,26 +40,26 @@ ROC_NODISCARD status::StatusCode Composer::align(core::Slice& buffer, roc_log(LogDebug, "rtp composer: not enough space for alignment: padding=%lu cap=%lu", (unsigned long)padding, (unsigned long)buffer.capacity()); - return status::StatusBadBuffer; + return false; } buffer.reslice(padding, padding); - return status::StatusOK; + return true; } else { return inner_composer_->align(buffer, header_size, payload_alignment); } } -ROC_NODISCARD status::StatusCode Composer::prepare(packet::Packet& packet, - core::Slice& buffer, - size_t payload_size) { +bool Composer::prepare(packet::Packet& packet, + core::Slice& buffer, + size_t payload_size) { core::Slice header = buffer.subslice(0, 0); if (header.capacity() < sizeof(Header)) { roc_log(LogDebug, "rtp composer: not enough space for rtp header: size=%lu cap=%lu", (unsigned long)sizeof(Header), (unsigned long)header.capacity()); - return status::StatusBadBuffer; + return false; } header.reslice(0, sizeof(Header)); @@ -70,14 +70,12 @@ ROC_NODISCARD status::StatusCode Composer::prepare(packet::Packet& packet, roc_log(LogDebug, "rtp composer: not enough space for rtp payload: size=%lu cap=%lu", (unsigned long)payload_size, (unsigned long)payload.capacity()); - return status::StatusBadBuffer; + return false; } payload.reslice(0, payload_size); } else { - status::StatusCode status = - inner_composer_->prepare(packet, payload, payload_size); - if (status != status::StatusOK) { - return status; + if (!inner_composer_->prepare(packet, payload, payload_size)) { + return false; } } @@ -90,11 +88,10 @@ ROC_NODISCARD status::StatusCode Composer::prepare(packet::Packet& packet, buffer.reslice(0, header.size() + payload.size()); - return status::StatusOK; + return true; } -ROC_NODISCARD status::StatusCode Composer::pad(packet::Packet& packet, - size_t padding_size) { +bool Composer::pad(packet::Packet& packet, size_t padding_size) { if (inner_composer_) { return inner_composer_->pad(packet, padding_size); } @@ -115,16 +112,16 @@ ROC_NODISCARD status::StatusCode Composer::pad(packet::Packet& packet, "rtp composer: padding is larger than payload size:" " payload_size=%lu padding_size=%lu", (unsigned long)rtp->payload.size(), (unsigned long)padding_size); - return status::StatusBadBuffer; + return false; } rtp->padding = rtp->payload.subslice(payload_size - padding_size, payload_size); rtp->payload = rtp->payload.subslice(0, payload_size - padding_size); - return status::StatusOK; + return true; } -ROC_NODISCARD status::StatusCode Composer::compose(packet::Packet& packet) { +bool Composer::compose(packet::Packet& packet) { packet::RTP* rtp = packet.rtp(); if (!rtp) { roc_panic("rtp composer: unexpected non-rtp packet"); @@ -155,7 +152,7 @@ ROC_NODISCARD status::StatusCode Composer::compose(packet::Packet& packet) { "rtp composer: padding is larger than supported by rtp:" " pad_size=%lu max_size=%lu", (unsigned long)padding_size, (unsigned long)(uint8_t)-1); - return status::StatusBadBuffer; + return false; } if (padding_size > 1) { @@ -168,7 +165,7 @@ ROC_NODISCARD status::StatusCode Composer::compose(packet::Packet& packet) { return inner_composer_->compose(packet); } - return status::StatusOK; + return true; } } // namespace rtp diff --git a/src/internal_modules/roc_rtp/composer.h b/src/internal_modules/roc_rtp/composer.h index 3e8a983d1..cce2a04dd 100644 --- a/src/internal_modules/roc_rtp/composer.h +++ b/src/internal_modules/roc_rtp/composer.h @@ -28,22 +28,21 @@ class Composer : public packet::IComposer, public core::NonCopyable<> { Composer(packet::IComposer* inner_composer, core::IArena& arena); //! Check if the object was successfully constructed. - ROC_NODISCARD virtual status::StatusCode init_status() const; + virtual status::StatusCode init_status() const; //! Adjust buffer to align payload. - ROC_NODISCARD virtual status::StatusCode + virtual bool align(core::Slice& buffer, size_t header_size, size_t payload_alignment); //! Prepare buffer for composing a packet. - ROC_NODISCARD virtual status::StatusCode + virtual bool prepare(packet::Packet& packet, core::Slice& buffer, size_t payload_size); //! Pad packet. - ROC_NODISCARD virtual status::StatusCode pad(packet::Packet& packet, - size_t padding_size); + virtual bool pad(packet::Packet& packet, size_t padding_size); //! Compose packet to buffer. - ROC_NODISCARD virtual status::StatusCode compose(packet::Packet& packet); + virtual bool compose(packet::Packet& packet); private: packet::IComposer* inner_composer_; diff --git a/src/internal_modules/roc_rtp/encoding.h b/src/internal_modules/roc_rtp/encoding.h index 68f441594..8fbf33c3a 100644 --- a/src/internal_modules/roc_rtp/encoding.h +++ b/src/internal_modules/roc_rtp/encoding.h @@ -70,7 +70,7 @@ struct Encoding { //! //! @returns //! false if string can't be parsed. -ROC_NODISCARD bool parse_encoding(const char* str, Encoding& result); +ROC_ATTR_NODISCARD bool parse_encoding(const char* str, Encoding& result); } // namespace rtp } // namespace roc diff --git a/src/internal_modules/roc_rtp/encoding_map.h b/src/internal_modules/roc_rtp/encoding_map.h index 0a6c1db83..5f0d29b04 100644 --- a/src/internal_modules/roc_rtp/encoding_map.h +++ b/src/internal_modules/roc_rtp/encoding_map.h @@ -38,7 +38,7 @@ class EncodingMap : public core::NonCopyable<> { explicit EncodingMap(core::IArena& arena); //! Add encoding to the map. - ROC_NODISCARD status::StatusCode register_encoding(Encoding enc); + ROC_ATTR_NODISCARD status::StatusCode register_encoding(Encoding enc); //! Find encoding by payload type. //! @returns diff --git a/src/internal_modules/roc_rtp/filter.h b/src/internal_modules/roc_rtp/filter.h index d7d722486..c8da54df9 100644 --- a/src/internal_modules/roc_rtp/filter.h +++ b/src/internal_modules/roc_rtp/filter.h @@ -65,8 +65,8 @@ class Filter : public packet::IReader, public core::NonCopyable<> { status::StatusCode init_status() const; //! Read next packet. - virtual ROC_NODISCARD status::StatusCode read(packet::PacketPtr& pp, - packet::PacketReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode read(packet::PacketPtr& pp, + packet::PacketReadMode mode); private: bool validate_(const packet::PacketPtr& packet); diff --git a/src/internal_modules/roc_rtp/headers.h b/src/internal_modules/roc_rtp/headers.h index 29fc3e424..8ce2e7d74 100644 --- a/src/internal_modules/roc_rtp/headers.h +++ b/src/internal_modules/roc_rtp/headers.h @@ -57,7 +57,7 @@ enum { //! | .... | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class Header { +ROC_ATTR_PACKED_BEGIN class Header { private: enum { //! @name RTP protocol version. @@ -223,7 +223,7 @@ ROC_PACKED_BEGIN class Header { roc_panic_if(index >= num_csrc()); return core::ntoh32u(ssrc_[index + 1]); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; //! RTP extension header. //! @@ -242,7 +242,7 @@ ROC_PACKED_BEGIN class Header { //! | .... | //! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //! @endcode -ROC_PACKED_BEGIN class ExtentionHeader { +ROC_ATTR_PACKED_BEGIN class ExtentionHeader { private: //! Extenson type. uint16_t type_; @@ -260,7 +260,7 @@ ROC_PACKED_BEGIN class ExtentionHeader { uint32_t data_size() const { return (uint32_t(core::ntoh16u(len_)) << 2); } -} ROC_PACKED_END; +} ROC_ATTR_PACKED_END; } // namespace rtp } // namespace roc diff --git a/src/internal_modules/roc_rtp/identity.cpp b/src/internal_modules/roc_rtp/identity.cpp index d84badc76..17976f2f6 100644 --- a/src/internal_modules/roc_rtp/identity.cpp +++ b/src/internal_modules/roc_rtp/identity.cpp @@ -7,16 +7,16 @@ */ #include "roc_rtp/identity.h" +#include "roc_core/fast_random.h" #include "roc_core/log.h" -#include "roc_core/secure_random.h" -#include "roc_status/status_code.h" +#include "roc_core/macro_helpers.h" namespace roc { namespace rtp { Identity::Identity() : init_status_(status::NoStatus) { - if (!core::uuid_generate(cname_, sizeof(cname_))) { + if (!core::uuid_generare(cname_, sizeof(cname_))) { init_status_ = status::StatusErrRand; return; } @@ -45,11 +45,9 @@ packet::stream_source_t Identity::ssrc() const { } status::StatusCode Identity::change_ssrc() { - bool ok = (packet::stream_source_t)core::secure_random_range_32( - 1, packet::stream_source_t(-1), ssrc_); - if (!ok) { - return status::StatusErrRand; - } + ssrc_ = + (packet::stream_source_t)core::fast_random_range(1, packet::stream_source_t(-1)); + roc_log(LogDebug, "rtp identity: ssrc=%lu cname=%s", (unsigned long)ssrc_, cname_); return status::StatusOK; diff --git a/src/internal_modules/roc_rtp/identity.h b/src/internal_modules/roc_rtp/identity.h index e8f734cb1..dda7274d3 100644 --- a/src/internal_modules/roc_rtp/identity.h +++ b/src/internal_modules/roc_rtp/identity.h @@ -42,7 +42,7 @@ class Identity : public core::NonCopyable<> { //! Regenerate SSRC. //! Used in case of SSRC collision. - ROC_NODISCARD status::StatusCode change_ssrc(); + ROC_ATTR_NODISCARD status::StatusCode change_ssrc(); private: char cname_[core::UuidLen + 1]; diff --git a/src/internal_modules/roc_rtp/link_meter.h b/src/internal_modules/roc_rtp/link_meter.h index a29145b13..3afa55e18 100644 --- a/src/internal_modules/roc_rtp/link_meter.h +++ b/src/internal_modules/roc_rtp/link_meter.h @@ -70,7 +70,7 @@ class LinkMeter : public packet::ILinkMeter, //! Write packet and update metrics. //! @remarks //! Invoked early in pipeline right after the packet is received. - virtual ROC_NODISCARD status::StatusCode write(const packet::PacketPtr& packet); + virtual ROC_ATTR_NODISCARD status::StatusCode write(const packet::PacketPtr& packet); private: void update_metrics_(const packet::Packet& packet); diff --git a/src/internal_modules/roc_rtp/parser.cpp b/src/internal_modules/roc_rtp/parser.cpp index edc9851f4..ea7b1d88b 100644 --- a/src/internal_modules/roc_rtp/parser.cpp +++ b/src/internal_modules/roc_rtp/parser.cpp @@ -25,12 +25,11 @@ status::StatusCode Parser::init_status() const { return status::StatusOK; } -status::StatusCode Parser::parse(packet::Packet& packet, - const core::Slice& buffer) { +bool Parser::parse(packet::Packet& packet, const core::Slice& buffer) { if (buffer.size() < sizeof(Header)) { roc_log(LogDebug, "rtp parser: bad packet: size<%d (rtp header)", (int)sizeof(Header)); - return status::StatusBadPacket; + return false; } const Header& header = *(const Header*)buffer.data(); @@ -38,7 +37,7 @@ status::StatusCode Parser::parse(packet::Packet& packet, if (header.version() != V2) { roc_log(LogDebug, "rtp parser: bad version: get=%d expected=%d", (int)header.version(), (int)V2); - return status::StatusBadPacket; + return false; } size_t header_size = header.header_size(); @@ -50,7 +49,7 @@ status::StatusCode Parser::parse(packet::Packet& packet, if (buffer.size() < header_size) { roc_log(LogDebug, "rtp parser: bad packet: size<%d (rtp header + ext header)", (int)header_size); - return status::StatusBadPacket; + return false; } if (header.has_extension()) { @@ -64,7 +63,7 @@ status::StatusCode Parser::parse(packet::Packet& packet, roc_log(LogDebug, "rtp parser: bad packet: size<%d (rtp header + ext header + ext data)", (int)header_size); - return status::StatusBadPacket; + return false; } size_t payload_begin = header_size; @@ -76,20 +75,20 @@ status::StatusCode Parser::parse(packet::Packet& packet, if (payload_begin == payload_end) { roc_log(LogDebug, "rtp parser: bad packet: empty payload but padding flag is set"); - return status::StatusBadPacket; + return false; } pad_size = buffer.data()[payload_end - 1]; if (pad_size == 0) { roc_log(LogDebug, "rtp parser: bad packet: padding size octet is zero"); - return status::StatusBadPacket; + return false; } if (size_t(payload_end - payload_begin) < size_t(pad_size)) { roc_log(LogDebug, "rtp parser: bad packet: padding_size>%d (payload size)", (int)(payload_end - payload_begin)); - return status::StatusBadPacket; + return false; } payload_end -= pad_size; @@ -119,7 +118,7 @@ status::StatusCode Parser::parse(packet::Packet& packet, return inner_parser_->parse(packet, rtp.payload); } - return status::StatusOK; + return true; } } // namespace rtp diff --git a/src/internal_modules/roc_rtp/parser.h b/src/internal_modules/roc_rtp/parser.h index 48969b194..7b5894379 100644 --- a/src/internal_modules/roc_rtp/parser.h +++ b/src/internal_modules/roc_rtp/parser.h @@ -37,8 +37,7 @@ class Parser : public packet::IParser, public core::NonCopyable<> { virtual status::StatusCode init_status() const; //! Parse packet from buffer. - virtual ROC_NODISCARD status::StatusCode parse(packet::Packet& packet, - const core::Slice& buffer); + virtual bool parse(packet::Packet& packet, const core::Slice& buffer); private: const EncodingMap& encoding_map_; diff --git a/src/internal_modules/roc_rtp/timestamp_extractor.h b/src/internal_modules/roc_rtp/timestamp_extractor.h index cc6258b62..ad6ca483e 100644 --- a/src/internal_modules/roc_rtp/timestamp_extractor.h +++ b/src/internal_modules/roc_rtp/timestamp_extractor.h @@ -33,7 +33,7 @@ class TimestampExtractor : public packet::IWriter, public core::NonCopyable<> { status::StatusCode init_status() const; //! Passes pkt downstream and remembers its capture and rtp timestamps. - virtual ROC_NODISCARD status::StatusCode write(const packet::PacketPtr& pkt); + virtual ROC_ATTR_NODISCARD status::StatusCode write(const packet::PacketPtr& pkt); //! Check if mapping already available. bool has_mapping(); diff --git a/src/internal_modules/roc_rtp/timestamp_injector.h b/src/internal_modules/roc_rtp/timestamp_injector.h index 89a54190a..0227b60db 100644 --- a/src/internal_modules/roc_rtp/timestamp_injector.h +++ b/src/internal_modules/roc_rtp/timestamp_injector.h @@ -36,8 +36,8 @@ class TimestampInjector : public packet::IReader, public core::NonCopyable<> { //! Get packet with filled capture ts field. //! @remarks //! If update_mapping has not been called yet, capture timestamp will be 0. - virtual ROC_NODISCARD status::StatusCode read(packet::PacketPtr& packet, - packet::PacketReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode read(packet::PacketPtr& packet, + packet::PacketReadMode mode); //! Get a pair of a reference timestamps. void update_mapping(core::nanoseconds_t capture_ts, diff --git a/src/internal_modules/roc_sdp/connection_data.h b/src/internal_modules/roc_sdp/connection_data.h index a32c09c57..ced53ca52 100644 --- a/src/internal_modules/roc_sdp/connection_data.h +++ b/src/internal_modules/roc_sdp/connection_data.h @@ -32,7 +32,7 @@ class ConnectionData { void clear(); //! Check and set connection address from a string. - ROC_NODISCARD bool + ROC_ATTR_NODISCARD bool set_connection_address(address::AddrFamily addrtype, const char* str, size_t str_len); //! The SocketAddr of the ConnectionData. diff --git a/src/internal_modules/roc_sdp/media_description.h b/src/internal_modules/roc_sdp/media_description.h index f045f5ae6..06c604574 100644 --- a/src/internal_modules/roc_sdp/media_description.h +++ b/src/internal_modules/roc_sdp/media_description.h @@ -71,22 +71,22 @@ class MediaDescription : public core::RefCounted { const char* guid() const; //! Set GUID - ROC_NODISCARD bool set_guid(const char* start_p_origin_username, - const char* end_p_origin_username, - const char* start_p_origin_sess_id, - const char* end_p_origin_sess_id, - const char* start_p_origin_nettype, - const char* end_p_origin_nettype, - const char* start_p_origin_addr, - const char* end_p_origin_addr); + ROC_ATTR_NODISCARD bool set_guid(const char* start_p_origin_username, + const char* end_p_origin_username, + const char* start_p_origin_sess_id, + const char* end_p_origin_sess_id, + const char* start_p_origin_nettype, + const char* end_p_origin_nettype, + const char* start_p_origin_addr, + const char* end_p_origin_addr); //! Origin unicast address. const address::SocketAddr& origin_unicast_address() const; //! Check and set origin unicast address from a string. - ROC_NODISCARD bool set_origin_unicast_address(address::AddrFamily addrtype, - const char* str, - size_t str_len); + ROC_ATTR_NODISCARD bool set_origin_unicast_address(address::AddrFamily addrtype, + const char* str, + size_t str_len); //! Check and set session connection address from a string. - ROC_NODISCARD bool set_session_connection_data(address::AddrFamily addrtype, - const char* str, - size_t str_len); + ROC_ATTR_NODISCARD bool set_session_connection_data(address::AddrFamily addrtype, + const char* str, + size_t str_len); //! Get reference to the connection data of the session. const ConnectionData& session_connection_data(); //! Create and add a new empty media description. - ROC_NODISCARD bool add_media_description(); + ROC_ATTR_NODISCARD bool add_media_description(); //! Get a shared pointer to the last added media description. const core::SharedPtr last_media_description() const; diff --git a/src/internal_modules/roc_sndio/backend_dispatcher.h b/src/internal_modules/roc_sndio/backend_dispatcher.h index 04139ae5c..a4b4df4e9 100644 --- a/src/internal_modules/roc_sndio/backend_dispatcher.h +++ b/src/internal_modules/roc_sndio/backend_dispatcher.h @@ -20,8 +20,8 @@ #include "roc_core/noncopyable.h" #include "roc_core/scoped_ptr.h" #include "roc_core/string_list.h" -#include "roc_sndio/device_defs.h" -#include "roc_sndio/driver_defs.h" +#include "roc_sndio/device_type.h" +#include "roc_sndio/driver.h" #include "roc_sndio/ibackend.h" #include "roc_sndio/isink.h" #include "roc_sndio/isource.h" @@ -38,35 +38,35 @@ class BackendDispatcher : public core::NonCopyable<> { core::IArena& arena); //! Create and open default sink. - ROC_NODISCARD status::StatusCode open_default_sink(const IoConfig& io_config, - core::ScopedPtr& result); + ROC_ATTR_NODISCARD status::StatusCode + open_default_sink(const IoConfig& io_config, core::ScopedPtr& result); //! Create and open default source. - ROC_NODISCARD status::StatusCode + ROC_ATTR_NODISCARD status::StatusCode open_default_source(const IoConfig& io_config, core::ScopedPtr& result); //! Create and open a sink. - ROC_NODISCARD status::StatusCode open_sink(const address::IoUri& uri, - const IoConfig& io_config, - core::ScopedPtr& result); + ROC_ATTR_NODISCARD status::StatusCode open_sink(const address::IoUri& uri, + const IoConfig& io_config, + core::ScopedPtr& result); //! Create and open a source. - ROC_NODISCARD status::StatusCode open_source(const address::IoUri& uri, - const IoConfig& io_config, - core::ScopedPtr& result); + ROC_ATTR_NODISCARD status::StatusCode open_source(const address::IoUri& uri, + const IoConfig& io_config, + core::ScopedPtr& result); //! Get all supported URI schemes. - ROC_NODISCARD bool get_supported_schemes(core::StringList& result); + ROC_ATTR_NODISCARD bool get_supported_schemes(core::StringList& result); //! Get all supported file formats. - ROC_NODISCARD bool get_supported_formats(core::StringList& result); + ROC_ATTR_NODISCARD bool get_supported_formats(core::StringList& result); //! Get all groups of sub-formats. - ROC_NODISCARD bool get_supported_subformat_groups(core::StringList& result); + ROC_ATTR_NODISCARD bool get_supported_subformat_groups(core::StringList& result); //! Get all sub-formats in group. - ROC_NODISCARD bool get_supported_subformats(const char* group, - core::StringList& result); + ROC_ATTR_NODISCARD bool get_supported_subformats(const char* group, + core::StringList& result); private: status::StatusCode open_default_device_(DeviceType device_type, diff --git a/src/internal_modules/roc_sndio/backend_map.h b/src/internal_modules/roc_sndio/backend_map.h index ccd9ff9b5..a9fe05ac6 100644 --- a/src/internal_modules/roc_sndio/backend_map.h +++ b/src/internal_modules/roc_sndio/backend_map.h @@ -15,7 +15,7 @@ #include "roc_core/noncopyable.h" #include "roc_core/optional.h" #include "roc_core/singleton.h" -#include "roc_sndio/driver_defs.h" +#include "roc_sndio/driver.h" #include "roc_sndio/ibackend.h" #ifdef ROC_TARGET_PULSEAUDIO diff --git a/src/internal_modules/roc_sndio/device_defs.cpp b/src/internal_modules/roc_sndio/device_state.cpp similarity index 74% rename from src/internal_modules/roc_sndio/device_defs.cpp rename to src/internal_modules/roc_sndio/device_state.cpp index d8d268f1e..a434fb719 100644 --- a/src/internal_modules/roc_sndio/device_defs.cpp +++ b/src/internal_modules/roc_sndio/device_state.cpp @@ -6,23 +6,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "roc_sndio/device_defs.h" +#include "roc_sndio/device_state.h" namespace roc { namespace sndio { -const char* device_type_to_str(DeviceType type) { - switch (type) { - case DeviceType_Sink: - return "sink"; - - case DeviceType_Source: - return "source"; - } - - return ""; -} - const char* device_state_to_str(DeviceState state) { switch (state) { case DeviceState_Active: @@ -39,6 +27,9 @@ const char* device_state_to_str(DeviceState state) { case DeviceState_Closed: return "closed"; + + default: + break; } return ""; diff --git a/src/internal_modules/roc_sndio/device_defs.h b/src/internal_modules/roc_sndio/device_state.h similarity index 74% rename from src/internal_modules/roc_sndio/device_defs.h rename to src/internal_modules/roc_sndio/device_state.h index e3e75042e..acb92fc15 100644 --- a/src/internal_modules/roc_sndio/device_defs.h +++ b/src/internal_modules/roc_sndio/device_state.h @@ -6,21 +6,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -//! @file roc_sndio/device_defs.h -//! @brief Device definitions. +//! @file roc_sndio/device_state.h +//! @brief Device state. -#ifndef ROC_SNDIO_DEVICE_DEFS_H_ -#define ROC_SNDIO_DEVICE_DEFS_H_ +#ifndef ROC_SNDIO_DEVICE_STATE_H_ +#define ROC_SNDIO_DEVICE_STATE_H_ namespace roc { namespace sndio { -//! Device type. -enum DeviceType { - DeviceType_Sink, //!< Sink. - DeviceType_Source //!< Source. -}; - //! Device state. enum DeviceState { //! Device is running and active. @@ -44,13 +38,10 @@ enum DeviceState { DeviceState_Closed = (1 << 4) }; -//! Convert device type to string. -const char* device_type_to_str(DeviceType type); - //! Convert device state to string. const char* device_state_to_str(DeviceState state); } // namespace sndio } // namespace roc -#endif // ROC_SNDIO_DEVICE_DEFS_H_ +#endif // ROC_SNDIO_DEVICE_STATE_H_ diff --git a/src/internal_modules/roc_sndio/device_type.cpp b/src/internal_modules/roc_sndio/device_type.cpp new file mode 100644 index 000000000..476dabfd3 --- /dev/null +++ b/src/internal_modules/roc_sndio/device_type.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Roc authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "roc_sndio/device_type.h" + +namespace roc { +namespace sndio { + +const char* device_type_to_str(DeviceType type) { + switch (type) { + case DeviceType_Sink: + return "sink"; + + case DeviceType_Source: + return "source"; + + default: + break; + } + + return ""; +} + +} // namespace sndio +} // namespace roc diff --git a/src/internal_modules/roc_sndio/device_type.h b/src/internal_modules/roc_sndio/device_type.h new file mode 100644 index 000000000..17cd195a5 --- /dev/null +++ b/src/internal_modules/roc_sndio/device_type.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Roc Streaming authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +//! @file roc_sndio/device_type.h +//! @brief Device type. + +#ifndef ROC_SNDIO_DEVICE_TYPE_H_ +#define ROC_SNDIO_DEVICE_TYPE_H_ + +namespace roc { +namespace sndio { + +//! Device type. +enum DeviceType { + DeviceType_Sink, //!< Sink. + DeviceType_Source //!< Source. +}; + +//! Convert device type to string. +const char* device_type_to_str(DeviceType type); + +} // namespace sndio +} // namespace roc + +#endif // ROC_SNDIO_DEVICE_TYPE_H_ diff --git a/src/internal_modules/roc_sndio/driver_defs.h b/src/internal_modules/roc_sndio/driver.h similarity index 94% rename from src/internal_modules/roc_sndio/driver_defs.h rename to src/internal_modules/roc_sndio/driver.h index e120e82de..2ba4422a0 100644 --- a/src/internal_modules/roc_sndio/driver_defs.h +++ b/src/internal_modules/roc_sndio/driver.h @@ -6,11 +6,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -//! @file roc_sndio/driver_defs.h -//! @brief Driver definitions. +//! @file roc_sndio/driver.h +//! @brief Driver information. -#ifndef ROC_SNDIO_DRIVER_DEFS_H_ -#define ROC_SNDIO_DRIVER_DEFS_H_ +#ifndef ROC_SNDIO_DRIVER_H_ +#define ROC_SNDIO_DRIVER_H_ #include "roc_core/panic.h" #include "roc_core/stddefs.h" @@ -115,4 +115,4 @@ struct FormatInfo { } // namespace sndio } // namespace roc -#endif // ROC_SNDIO_DRIVER_DEFS_H_ +#endif // ROC_SNDIO_DRIVER_H_ diff --git a/src/internal_modules/roc_sndio/ibackend.h b/src/internal_modules/roc_sndio/ibackend.h index ede5b4bad..9abb1af6d 100644 --- a/src/internal_modules/roc_sndio/ibackend.h +++ b/src/internal_modules/roc_sndio/ibackend.h @@ -17,8 +17,8 @@ #include "roc_core/attributes.h" #include "roc_core/iarena.h" #include "roc_core/string_list.h" -#include "roc_sndio/device_defs.h" -#include "roc_sndio/driver_defs.h" +#include "roc_sndio/device_type.h" +#include "roc_sndio/driver.h" #include "roc_sndio/idevice.h" #include "roc_sndio/io_config.h" #include "roc_status/status_code.h" @@ -38,22 +38,23 @@ class IBackend { virtual const char* name() const = 0; //! Append supported drivers to the list. - virtual ROC_NODISCARD bool + virtual ROC_ATTR_NODISCARD bool discover_drivers(core::Array& result) = 0; //! Append supported formats to the list. - virtual ROC_NODISCARD bool + virtual ROC_ATTR_NODISCARD bool discover_formats(core::Array& result) = 0; //! Append supported groups of sub-formats to the list. - virtual ROC_NODISCARD bool discover_subformat_groups(core::StringList& result) = 0; + virtual ROC_ATTR_NODISCARD bool + discover_subformat_groups(core::StringList& result) = 0; //! Append supported sub-formats of a group to the list. - virtual ROC_NODISCARD bool discover_subformats(const char* group, - core::StringList& result) = 0; + virtual ROC_ATTR_NODISCARD bool discover_subformats(const char* group, + core::StringList& result) = 0; //! Create and open a sink or source. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode open_device(DeviceType device_type, const char* driver, const char* path, diff --git a/src/internal_modules/roc_sndio/idevice.h b/src/internal_modules/roc_sndio/idevice.h index 1c2b300ee..5ba59b141 100644 --- a/src/internal_modules/roc_sndio/idevice.h +++ b/src/internal_modules/roc_sndio/idevice.h @@ -16,7 +16,8 @@ #include "roc_core/attributes.h" #include "roc_core/stddefs.h" #include "roc_core/time.h" -#include "roc_sndio/device_defs.h" +#include "roc_sndio/device_state.h" +#include "roc_sndio/device_type.h" #include "roc_status/status_code.h" namespace roc { @@ -88,7 +89,7 @@ class IDevice : public core::ArenaAllocation { //! After device is paused, there should be no I/O until it's resumed. //! @note //! Makes sense only if has_state() is true. - virtual ROC_NODISCARD status::StatusCode pause(); + virtual ROC_ATTR_NODISCARD status::StatusCode pause(); //! Resume device after pause. //! @remarks @@ -97,7 +98,7 @@ class IDevice : public core::ArenaAllocation { //! After device is paused, it should be resumed to do I/O again. //! @note //! Makes sense only if has_state() is true. - virtual ROC_NODISCARD status::StatusCode resume(); + virtual ROC_ATTR_NODISCARD status::StatusCode resume(); //! Check if the device supports latency reports. //! @remarks @@ -130,7 +131,7 @@ class IDevice : public core::ArenaAllocation { //! This method should be called to release resources held by the device. //! If this method is not called before the destructor, it's called //! automatically, but you won't know if error happened. - virtual ROC_NODISCARD status::StatusCode close() = 0; + virtual ROC_ATTR_NODISCARD status::StatusCode close() = 0; //! Destroy object and return memory to arena. //! @remarks diff --git a/src/internal_modules/roc_sndio/io_pump.h b/src/internal_modules/roc_sndio/io_pump.h index 86d486893..6724e2e1a 100644 --- a/src/internal_modules/roc_sndio/io_pump.h +++ b/src/internal_modules/roc_sndio/io_pump.h @@ -59,7 +59,7 @@ class IoPump : public core::NonCopyable<> { //! @remarks //! Run until the stop() is called or, if oneshot mode is enabled, //! the source becomes inactive. - ROC_NODISCARD status::StatusCode run(); + ROC_ATTR_NODISCARD status::StatusCode run(); //! Stop the pump. //! @remarks diff --git a/src/internal_modules/roc_sndio/isink.h b/src/internal_modules/roc_sndio/isink.h index 70ac0dcfb..9e48b9f6e 100644 --- a/src/internal_modules/roc_sndio/isink.h +++ b/src/internal_modules/roc_sndio/isink.h @@ -29,7 +29,7 @@ class ISink : virtual public IDevice, public audio::IFrameWriter { virtual ~ISink(); //! Flush buffered data, if any. - virtual ROC_NODISCARD status::StatusCode flush() = 0; + virtual ROC_ATTR_NODISCARD status::StatusCode flush() = 0; }; } // namespace sndio diff --git a/src/internal_modules/roc_sndio/isource.h b/src/internal_modules/roc_sndio/isource.h index 65fe8bbfc..17c0c88cd 100644 --- a/src/internal_modules/roc_sndio/isource.h +++ b/src/internal_modules/roc_sndio/isource.h @@ -32,7 +32,7 @@ class ISource : virtual public IDevice, public audio::IFrameReader { //! @remarks //! If the source has any sense of "beginning", this operation should rewind //! reading to the beginning. Otherwise it can be no-op. - virtual ROC_NODISCARD status::StatusCode rewind() = 0; + virtual ROC_ATTR_NODISCARD status::StatusCode rewind() = 0; //! Adjust source clock to match consumer clock. //! @remarks diff --git a/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_backend.cpp b/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_backend.cpp index 66c3ebd4e..4320aeb9c 100644 --- a/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_backend.cpp +++ b/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_backend.cpp @@ -10,7 +10,7 @@ #include "roc_core/log.h" #include "roc_core/scoped_ptr.h" #include "roc_core/stddefs.h" -#include "roc_sndio/driver_defs.h" +#include "roc_sndio/driver.h" #include "roc_sndio/pulseaudio_device.h" #include "roc_status/code_to_str.h" diff --git a/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_backend.h b/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_backend.h index b0eea6610..da3aa69cb 100644 --- a/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_backend.h +++ b/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_backend.h @@ -27,22 +27,22 @@ class PulseaudioBackend : public IBackend, core::NonCopyable<> { virtual const char* name() const; //! Append supported drivers to the list. - virtual ROC_NODISCARD bool + virtual ROC_ATTR_NODISCARD bool discover_drivers(core::Array& result); //! Append supported formats to the list. - virtual ROC_NODISCARD bool + virtual ROC_ATTR_NODISCARD bool discover_formats(core::Array& result); //! Append supported groups of sub-formats to the list. - virtual ROC_NODISCARD bool discover_subformat_groups(core::StringList& result); + virtual ROC_ATTR_NODISCARD bool discover_subformat_groups(core::StringList& result); //! Append supported sub-formats of a group to the list. - virtual ROC_NODISCARD bool discover_subformats(const char* group, - core::StringList& result); + virtual ROC_ATTR_NODISCARD bool discover_subformats(const char* group, + core::StringList& result); //! Create and open a sink or source. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode open_device(DeviceType device_type, const char* driver, const char* path, diff --git a/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_device.h b/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_device.h index 4908664b6..29e0b0a94 100644 --- a/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_device.h +++ b/src/internal_modules/roc_sndio/target_pulseaudio/roc_sndio/pulseaudio_device.h @@ -66,10 +66,10 @@ class PulseaudioDevice : public ISink, public ISource, public core::NonCopyable< virtual DeviceState state() const; //! Pause device. - virtual ROC_NODISCARD status::StatusCode pause(); + virtual ROC_ATTR_NODISCARD status::StatusCode pause(); //! Resume device. - virtual ROC_NODISCARD status::StatusCode resume(); + virtual ROC_ATTR_NODISCARD status::StatusCode resume(); //! Check if the device supports latency reports. virtual bool has_latency() const; @@ -81,7 +81,7 @@ class PulseaudioDevice : public ISink, public ISource, public core::NonCopyable< virtual bool has_clock() const; //! Restart reading from beginning. - virtual ROC_NODISCARD status::StatusCode rewind(); + virtual ROC_ATTR_NODISCARD status::StatusCode rewind(); //! Adjust device clock to match consumer clock. virtual void reclock(core::nanoseconds_t timestamp); @@ -89,20 +89,21 @@ class PulseaudioDevice : public ISink, public ISource, public core::NonCopyable< //! Write frame. //! @note //! Used if device is sink. - virtual ROC_NODISCARD status::StatusCode write(audio::Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(audio::Frame& frame); //! Read frame. //! @note //! Used if device is source. - virtual ROC_NODISCARD status::StatusCode read(audio::Frame& frame, - packet::stream_timestamp_t duration, - audio::FrameReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode + read(audio::Frame& frame, + packet::stream_timestamp_t duration, + audio::FrameReadMode mode); //! Flush buffered data, if any. - virtual ROC_NODISCARD status::StatusCode flush(); + virtual ROC_ATTR_NODISCARD status::StatusCode flush(); //! Explicitly close the device. - virtual ROC_NODISCARD status::StatusCode close(); + virtual ROC_ATTR_NODISCARD status::StatusCode close(); //! Destroy object and return memory to arena. virtual void dispose(); diff --git a/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_backend.h b/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_backend.h index 66e0e52d9..268193a29 100644 --- a/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_backend.h +++ b/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_backend.h @@ -27,22 +27,22 @@ class SndfileBackend : public IBackend, core::NonCopyable<> { virtual const char* name() const; //! Append supported drivers to the list. - virtual ROC_NODISCARD bool + virtual ROC_ATTR_NODISCARD bool discover_drivers(core::Array& result); //! Append supported formats to the list. - virtual ROC_NODISCARD bool + virtual ROC_ATTR_NODISCARD bool discover_formats(core::Array& result); //! Append supported groups of sub-formats to the list. - virtual ROC_NODISCARD bool discover_subformat_groups(core::StringList& result); + virtual ROC_ATTR_NODISCARD bool discover_subformat_groups(core::StringList& result); //! Append supported sub-formats of a group to the list. - virtual ROC_NODISCARD bool discover_subformats(const char* group, - core::StringList& result); + virtual ROC_ATTR_NODISCARD bool discover_subformats(const char* group, + core::StringList& result); //! Create and open a sink or source. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode open_device(DeviceType device_type, const char* driver, const char* path, diff --git a/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_helpers.h b/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_helpers.h index f08fa1c1d..50cc1efb5 100644 --- a/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_helpers.h +++ b/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_helpers.h @@ -22,21 +22,20 @@ namespace roc { namespace sndio { //! Choose sndfile major format from sample spec and path. -ROC_NODISCARD status::StatusCode sndfile_select_major_format( +ROC_ATTR_NODISCARD status::StatusCode sndfile_select_major_format( SF_INFO& file_info, audio::SampleSpec& sample_spec, const char* path); //! Choose sndfile sub-format from sample spec and path. -ROC_NODISCARD status::StatusCode sndfile_select_sub_format(SF_INFO& file_info, - audio::SampleSpec& sample_spec, - const char* path); +ROC_ATTR_NODISCARD status::StatusCode sndfile_select_sub_format( + SF_INFO& file_info, audio::SampleSpec& sample_spec, const char* path); //! Check that requested specification is valid for given input file. -ROC_NODISCARD status::StatusCode sndfile_check_input_spec( +ROC_ATTR_NODISCARD status::StatusCode sndfile_check_input_spec( const SF_INFO& file_info, const audio::SampleSpec& sample_spec, const char* path); //! Detect format and sub-format of opened file and fill sample spec. -ROC_NODISCARD status::StatusCode sndfile_detect_format(const SF_INFO& file_info, - audio::SampleSpec& sample_spec); +ROC_ATTR_NODISCARD status::StatusCode +sndfile_detect_format(const SF_INFO& file_info, audio::SampleSpec& sample_spec); } // namespace sndio } // namespace roc diff --git a/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_sink.h b/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_sink.h index f849ef26f..18ca1150c 100644 --- a/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_sink.h +++ b/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_sink.h @@ -65,13 +65,13 @@ class SndfileSink : public ISink, public core::NonCopyable<> { virtual bool has_clock() const; //! Write frame. - virtual ROC_NODISCARD status::StatusCode write(audio::Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(audio::Frame& frame); //! Flush buffered data, if any. - virtual ROC_NODISCARD status::StatusCode flush(); + virtual ROC_ATTR_NODISCARD status::StatusCode flush(); //! Explicitly close the sink. - virtual ROC_NODISCARD status::StatusCode close(); + virtual ROC_ATTR_NODISCARD status::StatusCode close(); //! Destroy object and return memory to arena. virtual void dispose(); diff --git a/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_source.h b/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_source.h index c2a8f9da6..2c1f73e91 100644 --- a/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_source.h +++ b/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_source.h @@ -66,18 +66,19 @@ class SndfileSource : public ISource, private core::NonCopyable<> { virtual bool has_clock() const; //! Restart reading from beginning. - virtual ROC_NODISCARD status::StatusCode rewind(); + virtual ROC_ATTR_NODISCARD status::StatusCode rewind(); //! Adjust source clock to match consumer clock. virtual void reclock(core::nanoseconds_t timestamp); //! Read frame. - virtual ROC_NODISCARD status::StatusCode read(audio::Frame& frame, - packet::stream_timestamp_t duration, - audio::FrameReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode + read(audio::Frame& frame, + packet::stream_timestamp_t duration, + audio::FrameReadMode mode); //! Explicitly close the source. - virtual ROC_NODISCARD status::StatusCode close(); + virtual ROC_ATTR_NODISCARD status::StatusCode close(); //! Destroy object and return memory to arena. virtual void dispose(); diff --git a/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_backend.h b/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_backend.h index 774de3e07..c939b57a1 100644 --- a/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_backend.h +++ b/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_backend.h @@ -29,22 +29,22 @@ class SoxBackend : public IBackend, core::NonCopyable<> { virtual const char* name() const; //! Append supported drivers to the list. - virtual ROC_NODISCARD bool + virtual ROC_ATTR_NODISCARD bool discover_drivers(core::Array& result); //! Append supported formats to the list. - virtual ROC_NODISCARD bool + virtual ROC_ATTR_NODISCARD bool discover_formats(core::Array& result); //! Append supported groups of sub-formats to the list. - virtual ROC_NODISCARD bool discover_subformat_groups(core::StringList& result); + virtual ROC_ATTR_NODISCARD bool discover_subformat_groups(core::StringList& result); //! Append supported sub-formats of a group to the list. - virtual ROC_NODISCARD bool discover_subformats(const char* group, - core::StringList& result); + virtual ROC_ATTR_NODISCARD bool discover_subformats(const char* group, + core::StringList& result); //! Create and open a sink or source. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode open_device(DeviceType device_type, const char* driver, const char* path, diff --git a/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_sink.h b/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_sink.h index c94e141e1..b99cc7e19 100644 --- a/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_sink.h +++ b/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_sink.h @@ -19,7 +19,7 @@ #include "roc_core/array.h" #include "roc_core/iarena.h" #include "roc_core/noncopyable.h" -#include "roc_sndio/driver_defs.h" +#include "roc_sndio/driver.h" #include "roc_sndio/io_config.h" #include "roc_sndio/isink.h" @@ -66,10 +66,10 @@ class SoxSink : public ISink, public core::NonCopyable<> { virtual DeviceState state() const; //! Pause sink. - virtual ROC_NODISCARD status::StatusCode pause(); + virtual ROC_ATTR_NODISCARD status::StatusCode pause(); //! Resume sink. - virtual ROC_NODISCARD status::StatusCode resume(); + virtual ROC_ATTR_NODISCARD status::StatusCode resume(); //! Check if the sink supports latency reports. virtual bool has_latency() const; @@ -78,13 +78,13 @@ class SoxSink : public ISink, public core::NonCopyable<> { virtual bool has_clock() const; //! Write frame. - virtual ROC_NODISCARD status::StatusCode write(audio::Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(audio::Frame& frame); //! Flush buffered data, if any. - virtual ROC_NODISCARD status::StatusCode flush(); + virtual ROC_ATTR_NODISCARD status::StatusCode flush(); //! Explicitly close the sink. - virtual ROC_NODISCARD status::StatusCode close(); + virtual ROC_ATTR_NODISCARD status::StatusCode close(); //! Destroy object and return memory to arena. virtual void dispose(); diff --git a/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_source.h b/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_source.h index 82e5d4330..7cbf82bce 100644 --- a/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_source.h +++ b/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_source.h @@ -20,7 +20,7 @@ #include "roc_core/iarena.h" #include "roc_core/noncopyable.h" #include "roc_core/string_buffer.h" -#include "roc_sndio/driver_defs.h" +#include "roc_sndio/driver.h" #include "roc_sndio/io_config.h" #include "roc_sndio/isource.h" @@ -67,10 +67,10 @@ class SoxSource : public ISource, private core::NonCopyable<> { virtual DeviceState state() const; //! Pause source. - virtual ROC_NODISCARD status::StatusCode pause(); + virtual ROC_ATTR_NODISCARD status::StatusCode pause(); //! Resume source. - virtual ROC_NODISCARD status::StatusCode resume(); + virtual ROC_ATTR_NODISCARD status::StatusCode resume(); //! Check if the source supports latency reports. virtual bool has_latency() const; @@ -79,18 +79,19 @@ class SoxSource : public ISource, private core::NonCopyable<> { virtual bool has_clock() const; //! Restart reading from beginning. - virtual ROC_NODISCARD status::StatusCode rewind(); + virtual ROC_ATTR_NODISCARD status::StatusCode rewind(); //! Adjust source clock to match consumer clock. virtual void reclock(core::nanoseconds_t timestamp); //! Read frame. - virtual ROC_NODISCARD status::StatusCode read(audio::Frame& frame, - packet::stream_timestamp_t duration, - audio::FrameReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode + read(audio::Frame& frame, + packet::stream_timestamp_t duration, + audio::FrameReadMode mode); //! Explicitly close the source. - virtual ROC_NODISCARD status::StatusCode close(); + virtual ROC_ATTR_NODISCARD status::StatusCode close(); //! Destroy object and return memory to arena. virtual void dispose(); diff --git a/src/internal_modules/roc_sndio/wav_backend.h b/src/internal_modules/roc_sndio/wav_backend.h index 8ae777f26..15f671dde 100644 --- a/src/internal_modules/roc_sndio/wav_backend.h +++ b/src/internal_modules/roc_sndio/wav_backend.h @@ -27,22 +27,22 @@ class WavBackend : public IBackend, core::NonCopyable<> { virtual const char* name() const; //! Append supported drivers to the list. - virtual ROC_NODISCARD bool + virtual ROC_ATTR_NODISCARD bool discover_drivers(core::Array& result); //! Append supported formats to the list. - virtual ROC_NODISCARD bool + virtual ROC_ATTR_NODISCARD bool discover_formats(core::Array& result); //! Append supported groups of sub-formats to the list. - virtual ROC_NODISCARD bool discover_subformat_groups(core::StringList& result); + virtual ROC_ATTR_NODISCARD bool discover_subformat_groups(core::StringList& result); //! Append supported sub-formats of a group to the list. - virtual ROC_NODISCARD bool discover_subformats(const char* group, - core::StringList& result); + virtual ROC_ATTR_NODISCARD bool discover_subformats(const char* group, + core::StringList& result); //! Create and open a sink or source. - virtual ROC_NODISCARD status::StatusCode + virtual ROC_ATTR_NODISCARD status::StatusCode open_device(DeviceType device_type, const char* driver, const char* path, diff --git a/src/internal_modules/roc_sndio/wav_header.h b/src/internal_modules/roc_sndio/wav_header.h index b58918c8f..068cd9ac9 100644 --- a/src/internal_modules/roc_sndio/wav_header.h +++ b/src/internal_modules/roc_sndio/wav_header.h @@ -32,7 +32,7 @@ const uint16_t WAV_FORMAT_IEEE_FLOAT = 0x0003; class WavHeader { public: //! WAV header data - ROC_PACKED_BEGIN struct WavHeaderData { + ROC_ATTR_PACKED_BEGIN struct WavHeaderData { //! Constructor WavHeaderData(uint32_t chunk_id, uint32_t chunk_size, @@ -78,7 +78,7 @@ class WavHeader { const uint32_t subchunk2_id; //! Subchunk2 size uint32_t subchunk2_size; - } ROC_PACKED_END; + } ROC_ATTR_PACKED_END; //! Initialize WavHeader(const uint16_t format_tag, diff --git a/src/internal_modules/roc_sndio/wav_sink.h b/src/internal_modules/roc_sndio/wav_sink.h index 03ed18e42..dec0b5e67 100644 --- a/src/internal_modules/roc_sndio/wav_sink.h +++ b/src/internal_modules/roc_sndio/wav_sink.h @@ -62,13 +62,13 @@ class WavSink : public ISink, public core::NonCopyable<> { virtual bool has_clock() const; //! Write frame. - virtual ROC_NODISCARD status::StatusCode write(audio::Frame& frame); + virtual ROC_ATTR_NODISCARD status::StatusCode write(audio::Frame& frame); //! Flush buffered data, if any. - virtual ROC_NODISCARD status::StatusCode flush(); + virtual ROC_ATTR_NODISCARD status::StatusCode flush(); //! Explicitly close the sink. - virtual ROC_NODISCARD status::StatusCode close(); + virtual ROC_ATTR_NODISCARD status::StatusCode close(); //! Destroy object and return memory to arena. virtual void dispose(); diff --git a/src/internal_modules/roc_sndio/wav_source.h b/src/internal_modules/roc_sndio/wav_source.h index 0d03351cf..e447aa4c8 100644 --- a/src/internal_modules/roc_sndio/wav_source.h +++ b/src/internal_modules/roc_sndio/wav_source.h @@ -63,18 +63,19 @@ class WavSource : public ISource, private core::NonCopyable<> { virtual bool has_clock() const; //! Restart reading from beginning. - virtual ROC_NODISCARD status::StatusCode rewind(); + virtual ROC_ATTR_NODISCARD status::StatusCode rewind(); //! Adjust source clock to match consumer clock. virtual void reclock(core::nanoseconds_t timestamp); //! Read frame. - virtual ROC_NODISCARD status::StatusCode read(audio::Frame& frame, - packet::stream_timestamp_t duration, - audio::FrameReadMode mode); + virtual ROC_ATTR_NODISCARD status::StatusCode + read(audio::Frame& frame, + packet::stream_timestamp_t duration, + audio::FrameReadMode mode); //! Explicitly close the source. - virtual ROC_NODISCARD status::StatusCode close(); + virtual ROC_ATTR_NODISCARD status::StatusCode close(); //! Destroy object and return memory to arena. virtual void dispose(); diff --git a/src/public_api/src/adapters.cpp b/src/public_api/src/adapters.cpp index 576ff9177..d7490488b 100644 --- a/src/public_api/src/adapters.cpp +++ b/src/public_api/src/adapters.cpp @@ -23,14 +23,14 @@ namespace api { namespace { -// Note: ROC_NOSANITIZE is used from *_from_user() functions because we don't +// Note: ROC_ATTR_NO_SANITIZE_UB is used from *_from_user() functions because we don't // want sanitizers to fail us when enums contain arbitrary values; we correctly handle // all these cases. #ifdef __clang__ // On clang, we use switches with original enum value. This allows compiler to warn us // if we forget to list a value. -template ROC_NOSANITIZE T enum_from_user(T t) { +template ROC_ATTR_NO_SANITIZE_UB T enum_from_user(T t) { return t; } #else @@ -38,7 +38,7 @@ template ROC_NOSANITIZE T enum_from_user(T t) { // some broken compiler versions (e.g. older gcc) to optimize out the code after switch // which corresponds to unmatched value. Clang does not have this problem, so we don't // use this hack on it to benefit from the warnings. -template ROC_NOSANITIZE int enum_from_user(T t) { +template ROC_ATTR_NO_SANITIZE_UB int enum_from_user(T t) { return t; } #endif @@ -51,7 +51,7 @@ template T clamp_counter(T value, T min_value, T max_value) { } // namespace -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool context_config_from_user(node::ContextConfig& out, const roc_context_config& in) { if (in.max_packet_size != 0) { out.max_packet_size = in.max_packet_size; @@ -64,7 +64,7 @@ bool context_config_from_user(node::ContextConfig& out, const roc_context_config return true; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool sender_config_from_user(node::Context& context, pipeline::SenderSinkConfig& out, const roc_sender_config& in) { @@ -178,7 +178,7 @@ bool sender_config_from_user(node::Context& context, return true; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool receiver_config_from_user(node::Context&, pipeline::ReceiverSourceConfig& out, const roc_receiver_config& in) { @@ -271,8 +271,8 @@ bool receiver_config_from_user(node::Context&, return true; } -ROC_NOSANITIZE bool interface_config_from_user(netio::UdpConfig& out, - const roc_interface_config& in) { +ROC_ATTR_NO_SANITIZE_UB bool interface_config_from_user(netio::UdpConfig& out, + const roc_interface_config& in) { if (in.outgoing_address[0] != '\0') { if (!out.bind_address.set_host_port_auto(in.outgoing_address, 0)) { roc_log(LogError, @@ -307,7 +307,7 @@ ROC_NOSANITIZE bool interface_config_from_user(netio::UdpConfig& out, return true; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool sample_spec_from_user(audio::SampleSpec& out, const roc_media_encoding& in) { if (!sample_format_from_user(out, in)) { return false; @@ -385,7 +385,7 @@ bool sample_spec_to_user(roc_media_encoding& out, const audio::SampleSpec& in) { return true; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool sample_format_from_user(audio::SampleSpec& out, const roc_media_encoding& in) { out.set_format(audio::Format_Invalid); out.set_pcm_subformat(audio::PcmSubformat_Invalid); @@ -656,7 +656,7 @@ bool sample_format_to_user(roc_media_encoding& out, const audio::SampleSpec& in) return true; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool channel_set_from_user(audio::ChannelSet& out, roc_channel_layout in_layout, unsigned int in_tracks) { @@ -716,7 +716,7 @@ bool channel_set_to_user(roc_channel_layout& out_layout, return false; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool clock_source_from_user(bool& out_timing, roc_clock_source in) { switch (enum_from_user(in)) { case ROC_CLOCK_SOURCE_DEFAULT: @@ -732,7 +732,7 @@ bool clock_source_from_user(bool& out_timing, roc_clock_source in) { return false; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool latency_tuner_backend_from_user(audio::LatencyTunerBackend& out, roc_latency_tuner_backend in) { switch (enum_from_user(in)) { @@ -748,7 +748,7 @@ bool latency_tuner_backend_from_user(audio::LatencyTunerBackend& out, return false; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool latency_tuner_profile_from_user(audio::LatencyTunerProfile& out, roc_latency_tuner_profile in) { switch (enum_from_user(in)) { @@ -772,7 +772,7 @@ bool latency_tuner_profile_from_user(audio::LatencyTunerProfile& out, return false; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool resampler_backend_from_user(audio::ResamplerBackend& out, roc_resampler_backend in) { switch (enum_from_user(in)) { case ROC_RESAMPLER_BACKEND_DEFAULT: @@ -795,7 +795,7 @@ bool resampler_backend_from_user(audio::ResamplerBackend& out, roc_resampler_bac return false; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool resampler_profile_from_user(audio::ResamplerProfile& out, roc_resampler_profile in) { switch (enum_from_user(in)) { case ROC_RESAMPLER_PROFILE_LOW: @@ -815,7 +815,7 @@ bool resampler_profile_from_user(audio::ResamplerProfile& out, roc_resampler_pro return false; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool plc_backend_from_user(int& out_id, roc_plc_backend in) { switch (enum_from_user(in)) { case ROC_PLC_BACKEND_DISABLE: @@ -835,7 +835,7 @@ bool plc_backend_from_user(int& out_id, roc_plc_backend in) { return false; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool packet_encoding_from_user(unsigned& out_id, roc_packet_encoding in) { switch (enum_from_user(in)) { case ROC_PACKET_ENCODING_AVP_L16_MONO: @@ -855,7 +855,7 @@ bool packet_encoding_from_user(unsigned& out_id, roc_packet_encoding in) { return false; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool fec_encoding_from_user(packet::FecScheme& out, roc_fec_encoding in) { switch (enum_from_user(in)) { case ROC_FEC_ENCODING_DISABLE: @@ -875,7 +875,7 @@ bool fec_encoding_from_user(packet::FecScheme& out, roc_fec_encoding in) { return false; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool interface_from_user(address::Interface& out, const roc_interface& in) { switch (enum_from_user(in)) { case ROC_INTERFACE_AGGREGATE: @@ -898,7 +898,7 @@ bool interface_from_user(address::Interface& out, const roc_interface& in) { return false; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB bool proto_from_user(address::Protocol& out, const roc_protocol& in) { switch (enum_from_user(in)) { case ROC_PROTO_RTSP: @@ -970,7 +970,7 @@ bool proto_to_user(roc_protocol& out, address::Protocol in) { return false; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB void receiver_slot_metrics_to_user(const pipeline::ReceiverSlotMetrics& slot_metrics, void* slot_arg) { roc_receiver_metrics& out = *(roc_receiver_metrics*)slot_arg; @@ -980,7 +980,7 @@ void receiver_slot_metrics_to_user(const pipeline::ReceiverSlotMetrics& slot_met out.connection_count = (unsigned)slot_metrics.num_participants; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB void receiver_participant_metrics_to_user( const pipeline::ReceiverParticipantMetrics& party_metrics, size_t party_index, @@ -1002,7 +1002,7 @@ void receiver_participant_metrics_to_user( } } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB void sender_slot_metrics_to_user(const pipeline::SenderSlotMetrics& slot_metrics, void* slot_arg) { roc_sender_metrics& out = *(roc_sender_metrics*)slot_arg; @@ -1012,7 +1012,7 @@ void sender_slot_metrics_to_user(const pipeline::SenderSlotMetrics& slot_metrics out.connection_count = (unsigned)slot_metrics.num_participants; } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB void sender_participant_metrics_to_user( const pipeline::SenderParticipantMetrics& party_metrics, size_t party_index, @@ -1048,7 +1048,7 @@ void link_metrics_to_user(roc_connection_metrics& out, const packet::LinkMetrics } } -ROC_NOSANITIZE +ROC_ATTR_NO_SANITIZE_UB LogLevel log_level_from_user(roc_log_level in) { switch (enum_from_user(in)) { case ROC_LOG_NONE: diff --git a/src/public_api/src/endpoint.cpp b/src/public_api/src/endpoint.cpp index 289057b43..7e68f54e8 100644 --- a/src/public_api/src/endpoint.cpp +++ b/src/public_api/src/endpoint.cpp @@ -42,7 +42,8 @@ int roc_endpoint_set_uri(roc_endpoint* endpoint, const char* uri) { address::NetworkUri& imp_endpoint = *(address::NetworkUri*)endpoint; - if (!address::parse_network_uri(uri, imp_endpoint)) { + if (!address::parse_network_uri(uri, address::NetworkUri::Subset_Full, + imp_endpoint)) { roc_log(LogError, "roc_endpoint_set_uri(): invalid arguments: invalid uri"); return -1; } @@ -115,7 +116,13 @@ int roc_endpoint_set_resource(roc_endpoint* endpoint, const char* encoded_resour address::NetworkUri& imp_endpoint = *(address::NetworkUri*)endpoint; - if (!address::parse_network_uri_resource(encoded_resource, imp_endpoint)) { + if (!encoded_resource) { + imp_endpoint.clear(address::NetworkUri::Subset_Resource); + return 0; + } + + if (!address::parse_network_uri(encoded_resource, + address::NetworkUri::Subset_Resource, imp_endpoint)) { roc_log(LogError, "roc_endpoint_set_resource(): invalid arguments: invalid resource"); return -1; @@ -139,7 +146,7 @@ int roc_endpoint_get_uri(const roc_endpoint* endpoint, char* buf, size_t* bufsz) core::StringBuilder b(buf, *bufsz); - if (!address::format_network_uri(imp_endpoint, b)) { + if (!address::format_network_uri(imp_endpoint, address::NetworkUri::Subset_Full, b)) { roc_log(LogError, "roc_endpoint_get_uri(): endpoint uri is not set"); return -1; } @@ -255,7 +262,8 @@ int roc_endpoint_get_resource(const roc_endpoint* endpoint, char* buf, size_t* b core::StringBuilder b(buf, *bufsz); - if (!address::format_network_uri_resource(imp_endpoint, b)) { + if (!address::format_network_uri(imp_endpoint, address::NetworkUri::Subset_Resource, + b)) { roc_log(LogDebug, "roc_endpoint_get_resource(): endpoint resource is not set"); return -1; } diff --git a/src/sanitizer_options.cpp b/src/sanitizer_options.cpp index 0486addfc..c9691f6b0 100644 --- a/src/sanitizer_options.cpp +++ b/src/sanitizer_options.cpp @@ -8,8 +8,8 @@ #include "roc_core/attributes.h" -extern "C" ROC_EXPORT ROC_NOSANITIZE const char* __ubsan_default_options(); +extern "C" ROC_ATTR_NO_SANITIZE_UB ROC_ATTR_EXPORT const char* __ubsan_default_options(); -extern "C" ROC_EXPORT ROC_NOSANITIZE const char* __ubsan_default_options() { +extern "C" ROC_ATTR_NO_SANITIZE_UB ROC_ATTR_EXPORT const char* __ubsan_default_options() { return "print_stacktrace=1"; } diff --git a/src/tests/public_api/test_endpoint.cpp b/src/tests/public_api/test_endpoint.cpp index d64833415..a2497df7b 100644 --- a/src/tests/public_api/test_endpoint.cpp +++ b/src/tests/public_api/test_endpoint.cpp @@ -380,7 +380,31 @@ TEST(endpoint, clear_parts) { CHECK(roc_endpoint_deallocate(endp) == 0); } - { // clear resource + { // clear resource (NULL) + roc_endpoint* endp = NULL; + CHECK(roc_endpoint_allocate(&endp) == 0); + + // set uri with resource + CHECK(roc_endpoint_set_uri(endp, "rtsp://1.2.3.4:567/path") == 0); + + // resource: yes + bufsz = sizeof(buf); + CHECK(roc_endpoint_get_resource(endp, buf, &bufsz) == 0); + + // clear resource + CHECK(roc_endpoint_set_resource(endp, NULL) == 0); + + // resource: no + bufsz = sizeof(buf); + CHECK(roc_endpoint_get_resource(endp, buf, &bufsz) == -1); + + // uri: yes + bufsz = sizeof(buf); + CHECK(roc_endpoint_get_uri(endp, buf, &bufsz) == 0); + + CHECK(roc_endpoint_deallocate(endp) == 0); + } + { // clear resource ("") roc_endpoint* endp = NULL; CHECK(roc_endpoint_allocate(&endp) == 0); @@ -1049,10 +1073,10 @@ TEST(endpoint, bad_args_set) { // resource: ok CHECK(roc_endpoint_set_resource(endp, "/path") == 0); + CHECK(roc_endpoint_set_resource(endp, NULL) == 0); CHECK(roc_endpoint_set_resource(endp, "") == 0); // resource: not ok - CHECK(roc_endpoint_set_resource(endp, NULL) == -1); CHECK(roc_endpoint_set_resource(NULL, "/path") == -1); CHECK(roc_endpoint_set_resource(endp, "BAD") == -1); diff --git a/src/tests/public_api/test_helpers/proxy.h b/src/tests/public_api/test_helpers/proxy.h index 1ddcc2d37..dac6d90ef 100644 --- a/src/tests/public_api/test_helpers/proxy.h +++ b/src/tests/public_api/test_helpers/proxy.h @@ -174,7 +174,7 @@ class Proxy : public core::Thread, private packet::IWriter { } } - virtual ROC_NODISCARD status::StatusCode write(const packet::PacketPtr& pp) { + virtual ROC_ATTR_NODISCARD status::StatusCode write(const packet::PacketPtr& pp) { pp->udp()->src_addr = send_config_.bind_address; if (pp->udp()->dst_addr == recv_source_config_.bind_address) { diff --git a/src/tests/roc_address/test_network_uri.cpp b/src/tests/roc_address/test_network_uri.cpp index 3ea494e57..b94cc2617 100644 --- a/src/tests/roc_address/test_network_uri.cpp +++ b/src/tests/roc_address/test_network_uri.cpp @@ -26,7 +26,7 @@ TEST_GROUP(network_uri) {}; TEST(network_uri, empty) { NetworkUri u(arena); - CHECK(!u.is_valid()); + CHECK(!u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_None, u.proto()); STRCMP_EQUAL("", u.host()); @@ -40,8 +40,8 @@ TEST(network_uri, empty) { TEST(network_uri, fields) { { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://host", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -53,8 +53,8 @@ TEST(network_uri, fields) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://host:123", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -66,8 +66,8 @@ TEST(network_uri, fields) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123/path", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://host:123/path", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -79,8 +79,8 @@ TEST(network_uri, fields) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123/", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://host:123/", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -92,8 +92,9 @@ TEST(network_uri, fields) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123/path?query", u)); - CHECK(u.is_valid()); + CHECK( + parse_network_uri("rtsp://host:123/path?query", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -105,8 +106,8 @@ TEST(network_uri, fields) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123?query", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://host:123?query", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -118,8 +119,8 @@ TEST(network_uri, fields) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123/?", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://host:123/?", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -131,8 +132,8 @@ TEST(network_uri, fields) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123?", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://host:123?", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -147,8 +148,8 @@ TEST(network_uri, fields) { TEST(network_uri, protocols) { { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://host:123", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -160,8 +161,8 @@ TEST(network_uri, protocols) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtp://host:123", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtp://host:123", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -173,8 +174,8 @@ TEST(network_uri, protocols) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtp+rs8m://host:123", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtp+rs8m://host:123", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTP_RS8M_Source, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -186,8 +187,8 @@ TEST(network_uri, protocols) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rs8m://host:123", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rs8m://host:123", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RS8M_Repair, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -199,8 +200,8 @@ TEST(network_uri, protocols) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtp+ldpc://host:123", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtp+ldpc://host:123", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTP_LDPC_Source, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -212,8 +213,8 @@ TEST(network_uri, protocols) { } { NetworkUri u(arena); - CHECK(parse_network_uri("ldpc://host:123", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("ldpc://host:123", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_LDPC_Repair, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -225,8 +226,8 @@ TEST(network_uri, protocols) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtcp://host:123", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtcp://host:123", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTCP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -241,8 +242,8 @@ TEST(network_uri, protocols) { TEST(network_uri, addresses) { { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://127.0.0.1:123", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://127.0.0.1:123", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("127.0.0.1", u.host()); @@ -254,8 +255,8 @@ TEST(network_uri, addresses) { } { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://[::1]:123", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://[::1]:123", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("[::1]", u.host()); @@ -271,8 +272,9 @@ TEST(network_uri, assign) { NetworkUri u1(arena); NetworkUri u2(arena); - CHECK(parse_network_uri("rtsp://127.0.0.1:123/path?query", u1)); - CHECK(u1.is_valid()); + CHECK(parse_network_uri("rtsp://127.0.0.1:123/path?query", NetworkUri::Subset_Full, + u1)); + CHECK(u1.verify(NetworkUri::Subset_Full)); CHECK(u2.assign(u1)); @@ -288,77 +290,83 @@ TEST(network_uri, assign) { TEST(network_uri, is_equal) { NetworkUri a1(arena); NetworkUri a2(arena); - CHECK(parse_network_uri("rtsp://127.0.0.1:123/path?query", a1)); - CHECK(parse_network_uri("rtsp://127.0.0.1:123/path?query", a2)); + CHECK(parse_network_uri("rtsp://127.0.0.1:123/path?query", NetworkUri::Subset_Full, + a1)); + CHECK(parse_network_uri("rtsp://127.0.0.1:123/path?query", NetworkUri::Subset_Full, + a2)); NetworkUri b1(arena); NetworkUri b2(arena); NetworkUri b3(arena); NetworkUri b4(arena); - CHECK(parse_network_uri("rtsp://127.0.0.2:123/path?query", b1)); - CHECK(parse_network_uri("rtsp://127.0.0.1:124/path?query", b2)); - CHECK(parse_network_uri("rtsp://127.0.0.1:123/patH?query", b3)); - CHECK(parse_network_uri("rtsp://127.0.0.1:123/path?querY", b4)); + CHECK(parse_network_uri("rtsp://127.0.0.2:123/path?query", NetworkUri::Subset_Full, + b1)); + CHECK(parse_network_uri("rtsp://127.0.0.1:124/path?query", NetworkUri::Subset_Full, + b2)); + CHECK(parse_network_uri("rtsp://127.0.0.1:123/patH?query", NetworkUri::Subset_Full, + b3)); + CHECK(parse_network_uri("rtsp://127.0.0.1:123/path?querY", NetworkUri::Subset_Full, + b4)); NetworkUri c1(arena); NetworkUri c2(arena); NetworkUri c3(arena); NetworkUri c4(arena); - CHECK(parse_network_uri("rtp://127.0.0.1:123", c1)); - CHECK(parse_network_uri("rtsp://127.0.0.1/path?query", c2)); - CHECK(parse_network_uri("rtsp://127.0.0.1:123/?query", c3)); - CHECK(parse_network_uri("rtsp://127.0.0.1:123/path", c4)); - - CHECK(a1 == a2); - CHECK(a2 == a1); - - CHECK(a1 != b1); - CHECK(a1 != b2); - CHECK(a1 != b3); - CHECK(a1 != b4); - - CHECK(b1 != a1); - CHECK(b2 != a1); - CHECK(b3 != a1); - CHECK(b4 != a1); - - CHECK(a1 != c1); - CHECK(a1 != c2); - CHECK(a1 != c3); - CHECK(a1 != c4); - - CHECK(c1 != a1); - CHECK(c2 != a1); - CHECK(c3 != a1); - CHECK(c4 != a1); + CHECK(parse_network_uri("rtp://127.0.0.1:123", NetworkUri::Subset_Full, c1)); + CHECK(parse_network_uri("rtsp://127.0.0.1/path?query", NetworkUri::Subset_Full, c2)); + CHECK(parse_network_uri("rtsp://127.0.0.1:123/?query", NetworkUri::Subset_Full, c3)); + CHECK(parse_network_uri("rtsp://127.0.0.1:123/path", NetworkUri::Subset_Full, c4)); + + CHECK(a1.is_equal(a2)); + CHECK(a2.is_equal(a1)); + + CHECK(!a1.is_equal(b1)); + CHECK(!a1.is_equal(b2)); + CHECK(!a1.is_equal(b3)); + CHECK(!a1.is_equal(b4)); + + CHECK(!b1.is_equal(a1)); + CHECK(!b2.is_equal(a1)); + CHECK(!b3.is_equal(a1)); + CHECK(!b4.is_equal(a1)); + + CHECK(!a1.is_equal(c1)); + CHECK(!a1.is_equal(c2)); + CHECK(!a1.is_equal(c3)); + CHECK(!a1.is_equal(c4)); + + CHECK(!c1.is_equal(a1)); + CHECK(!c2.is_equal(a1)); + CHECK(!c3.is_equal(a1)); + CHECK(!c4.is_equal(a1)); } TEST(network_uri, omit_port) { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123", u)); - CHECK(parse_network_uri("rtsp://host", u)); + CHECK(parse_network_uri("rtsp://host:123", NetworkUri::Subset_Full, u)); + CHECK(parse_network_uri("rtsp://host", NetworkUri::Subset_Full, u)); - CHECK(parse_network_uri("rtp://host:123", u)); - CHECK(!parse_network_uri("rtp://host", u)); + CHECK(parse_network_uri("rtp://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtp://host", NetworkUri::Subset_Full, u)); - CHECK(parse_network_uri("rtp+rs8m://host:123", u)); - CHECK(!parse_network_uri("rtp+rs8m://host", u)); + CHECK(parse_network_uri("rtp+rs8m://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtp+rs8m://host", NetworkUri::Subset_Full, u)); - CHECK(parse_network_uri("rs8m://host:123", u)); - CHECK(!parse_network_uri("rs8m://host", u)); + CHECK(parse_network_uri("rs8m://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rs8m://host", NetworkUri::Subset_Full, u)); - CHECK(parse_network_uri("rtp+ldpc://host:123", u)); - CHECK(!parse_network_uri("rtp+ldpc://host", u)); + CHECK(parse_network_uri("rtp+ldpc://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtp+ldpc://host", NetworkUri::Subset_Full, u)); - CHECK(parse_network_uri("ldpc://host:123", u)); - CHECK(!parse_network_uri("ldpc://host", u)); + CHECK(parse_network_uri("ldpc://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("ldpc://host", NetworkUri::Subset_Full, u)); } TEST(network_uri, zero_port) { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:0", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://host:0", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("host", u.host()); @@ -372,23 +380,25 @@ TEST(network_uri, zero_port) { TEST(network_uri, service) { { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://127.0.0.1:123", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://127.0.0.1:123", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("127.0.0.1", u.host()); LONGS_EQUAL(123, u.port()); + STRCMP_EQUAL("123", u.service()); STRCMP_EQUAL("rtsp://127.0.0.1:123", network_uri_to_str(u).c_str()); } { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://127.0.0.1", u)); - CHECK(u.is_valid()); + CHECK(parse_network_uri("rtsp://127.0.0.1", NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("127.0.0.1", u.host()); LONGS_EQUAL(-1, u.port()); + STRCMP_EQUAL("554", u.service()); STRCMP_EQUAL("rtsp://127.0.0.1", network_uri_to_str(u).c_str()); } @@ -397,29 +407,29 @@ TEST(network_uri, service) { TEST(network_uri, non_empty_path) { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123", u)); - CHECK(parse_network_uri("rtsp://host:123/path", u)); - CHECK(parse_network_uri("rtsp://host:123?query", u)); + CHECK(parse_network_uri("rtsp://host:123", NetworkUri::Subset_Full, u)); + CHECK(parse_network_uri("rtsp://host:123/path", NetworkUri::Subset_Full, u)); + CHECK(parse_network_uri("rtsp://host:123?query", NetworkUri::Subset_Full, u)); - CHECK(parse_network_uri("rtp://host:123", u)); - CHECK(!parse_network_uri("rtp://host:123/path", u)); - CHECK(!parse_network_uri("rtp://host:123?query", u)); + CHECK(parse_network_uri("rtp://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtp://host:123/path", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtp://host:123?query", NetworkUri::Subset_Full, u)); - CHECK(parse_network_uri("rtp+rs8m://host:123", u)); - CHECK(!parse_network_uri("rtp+rs8m://host:123/path", u)); - CHECK(!parse_network_uri("rtp+rs8m://host:123?query", u)); + CHECK(parse_network_uri("rtp+rs8m://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtp+rs8m://host:123/path", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtp+rs8m://host:123?query", NetworkUri::Subset_Full, u)); - CHECK(parse_network_uri("rs8m://host:123", u)); - CHECK(!parse_network_uri("rs8m://host:123/path", u)); - CHECK(!parse_network_uri("rs8m://host:123?query", u)); + CHECK(parse_network_uri("rs8m://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rs8m://host:123/path", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rs8m://host:123?query", NetworkUri::Subset_Full, u)); - CHECK(parse_network_uri("rtp+ldpc://host:123", u)); - CHECK(!parse_network_uri("rtp+ldpc://host:123/path", u)); - CHECK(!parse_network_uri("rtp+ldpc://host:123?query", u)); + CHECK(parse_network_uri("rtp+ldpc://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtp+ldpc://host:123/path", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtp+ldpc://host:123?query", NetworkUri::Subset_Full, u)); - CHECK(parse_network_uri("ldpc://host:123", u)); - CHECK(!parse_network_uri("ldpc://host:123/path", u)); - CHECK(!parse_network_uri("ldpc://host:123?query", u)); + CHECK(parse_network_uri("ldpc://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("ldpc://host:123/path", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("ldpc://host:123?query", NetworkUri::Subset_Full, u)); } TEST(network_uri, percent_encoding) { @@ -429,8 +439,8 @@ TEST(network_uri, percent_encoding) { ":123" "/foo%21bar%40baz%2Fqux%3Fwee" "?foo%21bar", - u)); - CHECK(u.is_valid()); + NetworkUri::Subset_Full, u)); + CHECK(u.verify(NetworkUri::Subset_Full)); LONGS_EQUAL(Proto_RTSP, u.proto()); STRCMP_EQUAL("foo-bar", u.host()); @@ -448,21 +458,21 @@ TEST(network_uri, percent_encoding) { TEST(network_uri, small_buffer) { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123/path?query", u)); + CHECK(parse_network_uri("rtsp://host:123/path?query", NetworkUri::Subset_Full, u)); char buf[sizeof("rtsp://host:123/path?query")]; { core::StringBuilder b(buf, sizeof(buf)); - CHECK(format_network_uri(u, b)); + CHECK(format_network_uri(u, NetworkUri::Subset_Full, b)); CHECK(b.is_ok()); } for (size_t i = 0; i < sizeof(buf); i++) { core::StringBuilder b(buf, i); - CHECK(format_network_uri(u, b)); + CHECK(format_network_uri(u, NetworkUri::Subset_Full, b)); CHECK(!b.is_ok()); } } @@ -470,36 +480,37 @@ TEST(network_uri, small_buffer) { TEST(network_uri, bad_syntax) { NetworkUri u(arena); - CHECK(parse_network_uri("rtsp://host:123", u)); - CHECK(!parse_network_uri("bad://host:123", u)); - - CHECK(!parse_network_uri("host:123", u)); - CHECK(!parse_network_uri("://host:123", u)); - CHECK(!parse_network_uri("rtsp://", u)); - CHECK(!parse_network_uri("rtsp://:123", u)); - CHECK(!parse_network_uri(" rtsp://host:123", u)); - CHECK(!parse_network_uri("rtp ://host:123", u)); - CHECK(!parse_network_uri("rtsp://host: 123", u)); - CHECK(!parse_network_uri("rtsp://host:123 ", u)); - - CHECK(!parse_network_uri("rtsp://host:port", u)); - CHECK(!parse_network_uri("rtsp://host:-1", u)); - CHECK(!parse_network_uri("rtsp://host:65536", u)); - - CHECK(!parse_network_uri("rtsp://host:123path", u)); - CHECK(!parse_network_uri("rtsp://host:123./path", u)); - - CHECK(!parse_network_uri("rtsp://host:123/path%", u)); - CHECK(!parse_network_uri("rtsp://host:123/path%--path", u)); - - CHECK(!parse_network_uri("rtsp://host:123/path?query#frag", u)); - CHECK(!parse_network_uri("rtsp://host:123/path?#frag", u)); - CHECK(!parse_network_uri("rtsp://host:123/path#frag", u)); - CHECK(!parse_network_uri("rtsp://host:123/#frag", u)); - CHECK(!parse_network_uri("rtsp://host:123#frag", u)); - CHECK(!parse_network_uri("rtsp://host:123#", u)); - - CHECK(!parse_network_uri("", u)); + CHECK(parse_network_uri("rtsp://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("bad://host:123", NetworkUri::Subset_Full, u)); + + CHECK(!parse_network_uri("host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri(" rtsp://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtp ://host:123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://host: 123", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://host:123 ", NetworkUri::Subset_Full, u)); + + CHECK(!parse_network_uri("rtsp://host:port", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://host:-1", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://host:65536", NetworkUri::Subset_Full, u)); + + CHECK(!parse_network_uri("rtsp://host:123path", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://host:123./path", NetworkUri::Subset_Full, u)); + + CHECK(!parse_network_uri("rtsp://host:123/path%", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://host:123/path%--path", NetworkUri::Subset_Full, u)); + + CHECK(!parse_network_uri("rtsp://host:123/path?query#frag", NetworkUri::Subset_Full, + u)); + CHECK(!parse_network_uri("rtsp://host:123/path?#frag", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://host:123/path#frag", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://host:123/#frag", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://host:123#frag", NetworkUri::Subset_Full, u)); + CHECK(!parse_network_uri("rtsp://host:123#", NetworkUri::Subset_Full, u)); + + CHECK(!parse_network_uri("", NetworkUri::Subset_Full, u)); } } // namespace address diff --git a/src/tests/roc_address/test_socket_addr.cpp b/src/tests/roc_address/test_socket_addr.cpp index 6014d459c..b45d20e90 100644 --- a/src/tests/roc_address/test_socket_addr.cpp +++ b/src/tests/roc_address/test_socket_addr.cpp @@ -157,35 +157,35 @@ TEST(socket_addr, multicast_ipv4) { SocketAddr addr; CHECK(addr.set_host_port(Family_IPv4, "223.255.255.255", 123)); CHECK(addr.has_host_port()); - CHECK(!addr.is_multicast()); + CHECK(!addr.multicast()); } { SocketAddr addr; CHECK(addr.set_host_port(Family_IPv4, "224.0.0.0", 123)); CHECK(addr.has_host_port()); - CHECK(addr.is_multicast()); + CHECK(addr.multicast()); } { SocketAddr addr; CHECK(addr.set_host_port(Family_IPv4, "227.128.128.128", 123)); CHECK(addr.has_host_port()); - CHECK(addr.is_multicast()); + CHECK(addr.multicast()); } { SocketAddr addr; CHECK(addr.set_host_port(Family_IPv4, "239.255.255.255", 123)); CHECK(addr.has_host_port()); - CHECK(addr.is_multicast()); + CHECK(addr.multicast()); } { SocketAddr addr; CHECK(addr.set_host_port(Family_IPv4, "240.0.0.0", 123)); CHECK(addr.has_host_port()); - CHECK(!addr.is_multicast()); + CHECK(!addr.multicast()); } } @@ -194,21 +194,21 @@ TEST(socket_addr, multicast_ipv6) { SocketAddr addr; CHECK(addr.set_host_port(Family_IPv6, "fe00::", 123)); CHECK(addr.has_host_port()); - CHECK(!addr.is_multicast()); + CHECK(!addr.multicast()); } { SocketAddr addr; CHECK(addr.set_host_port(Family_IPv6, "ff00::", 123)); CHECK(addr.has_host_port()); - CHECK(addr.is_multicast()); + CHECK(addr.multicast()); } { SocketAddr addr; CHECK(addr.set_host_port(Family_IPv6, "ff11:1:1:1:1:1:1:1", 123)); CHECK(addr.has_host_port()); - CHECK(addr.is_multicast()); + CHECK(addr.multicast()); } { @@ -216,7 +216,7 @@ TEST(socket_addr, multicast_ipv6) { CHECK(addr.set_host_port(Family_IPv6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 123)); CHECK(addr.has_host_port()); - CHECK(addr.is_multicast()); + CHECK(addr.multicast()); } } diff --git a/src/tests/roc_audio/test_depacketizer.cpp b/src/tests/roc_audio/test_depacketizer.cpp index 29812ba8f..d24edd48c 100644 --- a/src/tests/roc_audio/test_depacketizer.cpp +++ b/src/tests/roc_audio/test_depacketizer.cpp @@ -62,9 +62,7 @@ packet::PacketPtr new_packet(IFrameEncoder& encoder, core::Slice bp = packet_factory.new_packet_buffer(); CHECK(bp); - LONGS_EQUAL( - status::StatusOK, - rtp_composer.prepare(*pp, bp, encoder.encoded_byte_count(SamplesPerPacket))); + CHECK(rtp_composer.prepare(*pp, bp, encoder.encoded_byte_count(SamplesPerPacket))); pp->set_buffer(bp); @@ -84,7 +82,7 @@ packet::PacketPtr new_packet(IFrameEncoder& encoder, encoder.end_frame(); - LONGS_EQUAL(status::StatusOK, rtp_composer.compose(*pp)); + CHECK(rtp_composer.compose(*pp)); return pp; } diff --git a/src/tests/roc_core/test_fast_random.cpp b/src/tests/roc_core/test_fast_random.cpp index cb5d15846..0f072d8d3 100644 --- a/src/tests/roc_core/test_fast_random.cpp +++ b/src/tests/roc_core/test_fast_random.cpp @@ -6,11 +6,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "roc_core/fast_random.h" -#include "roc_core/stddefs.h" +// see also test_secure_random.cpp #include +#include "roc_core/fast_random.h" +#include "roc_core/stddefs.h" + namespace roc { namespace core { diff --git a/src/tests/roc_core/test_secure_random.cpp b/src/tests/roc_core/test_secure_random.cpp deleted file mode 100644 index b6bd01d96..000000000 --- a/src/tests/roc_core/test_secure_random.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2025 Roc Streaming authors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "roc_core/macro_helpers.h" -#include "roc_core/secure_random.h" -#include "roc_core/stddefs.h" - -#include -#include - -namespace roc { -namespace core { - -TEST_GROUP(secure_random) {}; - -TEST(secure_random, buf_len) { - unsigned char buf[64] = { 0 }; - - bool ok = secure_random(&buf[5], 50); - CHECK_TRUE(ok); - - for (size_t i = 0; i < 5; i++) { - BYTES_EQUAL(0, buf[i]); - } - - for (size_t i = 55; i < ROC_ARRAY_SIZE(buf); i++) { - BYTES_EQUAL(0, buf[i]); - } -} - -TEST(secure_random, some_trivial_corner_cases) { - CHECK_TRUE(secure_random(NULL, 0)); - - uint32_t res32; - CHECK_TRUE(secure_random_range_32(12345, 12345, res32)); - UNSIGNED_LONGS_EQUAL(12345, res32); - - uint64_t res64; - CHECK_TRUE(secure_random_range_64(444555666, 444555666, res64)); - UNSIGNED_LONGS_EQUAL(444555666, res64); - - CHECK_TRUE(secure_random_range_32(0, UINT32_MAX, res32)); - CHECK_TRUE(secure_random_range_64(0, UINT64_MAX, res64)); -} - -TEST(secure_random, sec32) { - uint32_t res32 = 0; - - for (uint32_t i = 0, j = 500; i < 250 && j > 250; i += 15, j -= 11) { - CHECK_TRUE(secure_random_range_32(i, j, res32)); - CHECK(i <= res32 && res32 <= j); - } -} - -TEST(secure_random, sec64) { - uint64_t res64 = 0; - - for (uint64_t i = 0, j = 500; i < 250 && j > 250; i += 15, j -= 11) { - CHECK_TRUE(secure_random_range_64(i, j, res64)); - CHECK(i <= res64 && res64 <= j); - } -} - -} // namespace core -} // namespace roc diff --git a/src/tests/roc_core/test_uuid.cpp b/src/tests/roc_core/test_uuid.cpp index f2876165c..3c2a82350 100644 --- a/src/tests/roc_core/test_uuid.cpp +++ b/src/tests/roc_core/test_uuid.cpp @@ -19,7 +19,7 @@ TEST(uuid, generate) { char a_uuid[UuidLen + 1]; memset(a_uuid, 0xcc, sizeof(a_uuid)); - CHECK(uuid_generate(a_uuid, sizeof(a_uuid)) == true); + CHECK(uuid_generare(a_uuid, sizeof(a_uuid)) == true); CHECK(a_uuid[8] == '-'); CHECK(a_uuid[13] == '-'); CHECK(a_uuid[18] == '-'); @@ -31,7 +31,7 @@ TEST(uuid, generated_with_bigger_buffer) { char a_uuid[UuidLen + 1 + 4]; memset(a_uuid, 0xcc, sizeof(a_uuid)); - CHECK(uuid_generate(a_uuid, sizeof(a_uuid)) == true); + CHECK(uuid_generare(a_uuid, sizeof(a_uuid)) == true); CHECK(a_uuid[8] == '-'); CHECK(a_uuid[13] == '-'); CHECK(a_uuid[18] == '-'); diff --git a/src/tests/roc_ctl/bench_task_queue_contention.cpp b/src/tests/roc_ctl/bench_task_queue_contention.cpp index f1f8452da..e5f8424e8 100644 --- a/src/tests/roc_ctl/bench_task_queue_contention.cpp +++ b/src/tests/roc_ctl/bench_task_queue_contention.cpp @@ -6,12 +6,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include + #include "roc_core/fast_random.h" #include "roc_ctl/control_task_executor.h" #include "roc_ctl/control_task_queue.h" -#include - namespace roc { namespace ctl { namespace { diff --git a/src/tests/roc_fec/test_block_encoder_decoder.cpp b/src/tests/roc_fec/test_block_encoder_decoder.cpp index 5e6a24bda..69ee55da6 100644 --- a/src/tests/roc_fec/test_block_encoder_decoder.cpp +++ b/src/tests/roc_fec/test_block_encoder_decoder.cpp @@ -11,10 +11,8 @@ #include "roc_core/array.h" #include "roc_core/fast_random.h" -#include "roc_core/heap_arena.h" #include "roc_core/log.h" #include "roc_core/scoped_ptr.h" -#include "roc_core/secure_random.h" #include "roc_fec/codec_map.h" namespace roc { @@ -94,11 +92,9 @@ class Codec { core::Slice make_buffer_(size_t p_size) { core::Slice buf = packet_factory_.new_packet_buffer(); buf.reslice(0, p_size); - for (size_t j = 0; j < buf.size(); ++j) { buf.data()[j] = (uint8_t)core::fast_random_range(0, 0xff); } - return buf; } diff --git a/src/tests/roc_fec/test_block_writer_reader.cpp b/src/tests/roc_fec/test_block_writer_reader.cpp index be1f2614a..3304138d6 100644 --- a/src/tests/roc_fec/test_block_writer_reader.cpp +++ b/src/tests/roc_fec/test_block_writer_reader.cpp @@ -119,9 +119,9 @@ TEST_GROUP(block_writer_reader) { void recompose_packet(const packet::PacketPtr& p) { if (p->flags() & packet::Packet::FlagRepair) { - LONGS_EQUAL(status::StatusOK, repair_composer().compose(*p)); + CHECK(repair_composer().compose(*p)); } else { - LONGS_EQUAL(status::StatusOK, source_composer().compose(*p)); + CHECK(source_composer().compose(*p)); } } @@ -145,7 +145,7 @@ TEST_GROUP(block_writer_reader) { if (!composer) { composer = &source_composer(); } - LONGS_EQUAL(status::StatusOK, composer->prepare(*pp, bp, rtp_payload_size)); + CHECK(composer->prepare(*pp, bp, rtp_payload_size)); pp->set_buffer(bp); @@ -1651,7 +1651,7 @@ TEST(block_writer_reader, zero_repair_packets) { // two blocks with NES == SBL if ((n_block == 2 || n_block == 4) && (i >= NumSourcePackets)) { p->fec()->block_length = NumSourcePackets; - LONGS_EQUAL(status::StatusOK, ldpc_repair_composer.compose(*p)); + ldpc_repair_composer.compose(*p); } LONGS_EQUAL(status::StatusOK, dispatcher.write(p)); @@ -2499,7 +2499,7 @@ TEST(block_writer_reader, reader_oversized_source_block) { if (i == 0) { // violates: SBL <= MAX_BLEN (for source packets) p->fec()->source_block_length = encoder->max_block_length() + 1; - LONGS_EQUAL(status::StatusOK, ldpc_source_composer.compose(*p)); + ldpc_source_composer.compose(*p); } LONGS_EQUAL(status::StatusOK, dispatcher.write(p)); @@ -2570,7 +2570,7 @@ TEST(block_writer_reader, reader_oversized_repair_block) { if (i == NumSourcePackets) { // violates: BLEN <= MAX_BLEN (for repair packets) p->fec()->block_length = encoder->max_block_length() + 1; - LONGS_EQUAL(status::StatusOK, ldpc_repair_composer.compose(*p)); + ldpc_repair_composer.compose(*p); } LONGS_EQUAL(status::StatusOK, dispatcher.write(p)); diff --git a/src/tests/roc_fec/test_block_writer_reader_duration.cpp b/src/tests/roc_fec/test_block_writer_reader_duration.cpp index 7f8ae589d..4e9e6da2c 100644 --- a/src/tests/roc_fec/test_block_writer_reader_duration.cpp +++ b/src/tests/roc_fec/test_block_writer_reader_duration.cpp @@ -96,9 +96,7 @@ TEST_GROUP(block_writer_reader_duration) { core::Slice bp = packet_factory.new_packet_buffer(); CHECK(bp); - LONGS_EQUAL( - status::StatusOK, - source_composer.prepare(*pp, bp, FECPayloadSize - sizeof(rtp::Header))); + CHECK(source_composer.prepare(*pp, bp, FECPayloadSize - sizeof(rtp::Header))); pp->set_buffer(bp); pp->add_flags(packet::Packet::FlagAudio | packet::Packet::FlagPrepared); diff --git a/src/tests/roc_fec/test_block_writer_reader_errors.cpp b/src/tests/roc_fec/test_block_writer_reader_errors.cpp index a2307ca8c..0333aa6ab 100644 --- a/src/tests/roc_fec/test_block_writer_reader_errors.cpp +++ b/src/tests/roc_fec/test_block_writer_reader_errors.cpp @@ -87,9 +87,7 @@ TEST_GROUP(block_writer_reader_errors) { core::Slice bp = packet_factory.new_packet_buffer(); CHECK(bp); - LONGS_EQUAL( - status::StatusOK, - source_composer.prepare(*pp, bp, FECPayloadSize - sizeof(rtp::Header))); + CHECK(source_composer.prepare(*pp, bp, FECPayloadSize - sizeof(rtp::Header))); pp->set_buffer(bp); pp->add_flags(packet::Packet::FlagAudio | packet::Packet::FlagPrepared); diff --git a/src/tests/roc_fec/test_block_writer_reader_peek.cpp b/src/tests/roc_fec/test_block_writer_reader_peek.cpp index c732771c4..fc47958f0 100644 --- a/src/tests/roc_fec/test_block_writer_reader_peek.cpp +++ b/src/tests/roc_fec/test_block_writer_reader_peek.cpp @@ -96,9 +96,7 @@ TEST_GROUP(block_writer_reader_peek) { core::Slice bp = packet_factory.new_packet_buffer(); CHECK(bp); - LONGS_EQUAL( - status::StatusOK, - source_composer.prepare(*pp, bp, FECPayloadSize - sizeof(rtp::Header))); + CHECK(source_composer.prepare(*pp, bp, FECPayloadSize - sizeof(rtp::Header))); pp->set_buffer(bp); pp->add_flags(packet::Packet::FlagAudio | packet::Packet::FlagPrepared); diff --git a/src/tests/roc_fec/test_composer.cpp b/src/tests/roc_fec/test_composer.cpp index c7288e55b..a4bfa9b08 100644 --- a/src/tests/roc_fec/test_composer.cpp +++ b/src/tests/roc_fec/test_composer.cpp @@ -42,7 +42,7 @@ TEST(composer, align_footer) { UNSIGNED_LONGS_EQUAL((unsigned long)buffer->data(), slice.data()); Composer composer(NULL, arena); - LONGS_EQUAL(status::StatusOK, composer.align(slice, 0, Alignment)); + CHECK(composer.align(slice, 0, Alignment)); UNSIGNED_LONGS_EQUAL(0, slice.size()); UNSIGNED_LONGS_EQUAL(BufferSize, slice.capacity()); @@ -65,7 +65,7 @@ TEST(composer, align_header) { CHECK(((unsigned long)slice.data() + sizeof(RS8M_PayloadID)) % Alignment != 0); Composer composer(NULL, arena); - LONGS_EQUAL(status::StatusOK, composer.align(slice, 0, Alignment)); + CHECK(composer.align(slice, 0, Alignment)); UNSIGNED_LONGS_EQUAL(0, slice.size()); UNSIGNED_LONGS_EQUAL(BufferSize - (Alignment - sizeof(RS8M_PayloadID)), @@ -93,7 +93,7 @@ TEST(composer, align_outer_header) { != 0); Composer composer(NULL, arena); - LONGS_EQUAL(status::StatusOK, composer.align(slice, OuterHeader, Alignment)); + CHECK(composer.align(slice, OuterHeader, Alignment)); UNSIGNED_LONGS_EQUAL(0, slice.size()); UNSIGNED_LONGS_EQUAL(BufferSize @@ -117,12 +117,12 @@ TEST(composer, packet_size) { Composer composer(NULL, arena); - LONGS_EQUAL(status::StatusOK, composer.align(buffer, 0, Alignment)); - LONGS_EQUAL(status::StatusOK, composer.prepare(*packet, buffer, PayloadSize)); + CHECK(composer.align(buffer, 0, Alignment)); + CHECK(composer.prepare(*packet, buffer, PayloadSize)); packet->set_buffer(buffer); - LONGS_EQUAL(status::StatusOK, composer.compose(*packet)); + CHECK(composer.compose(*packet)); UNSIGNED_LONGS_EQUAL(sizeof(RS8M_PayloadID) + PayloadSize, packet->buffer().size()); } diff --git a/src/tests/roc_fec/test_composer_parser.cpp b/src/tests/roc_fec/test_composer_parser.cpp index 8e9057dfc..2694a49ec 100644 --- a/src/tests/roc_fec/test_composer_parser.cpp +++ b/src/tests/roc_fec/test_composer_parser.cpp @@ -169,14 +169,13 @@ void test_compose(const PacketTest& test) { packet::PacketPtr packet = packet_factory.new_packet(); CHECK(packet); - LONGS_EQUAL(status::StatusOK, - test.composer->prepare(*packet, buffer, Test_payload_size)); + CHECK(test.composer->prepare(*packet, buffer, Test_payload_size)); packet->set_buffer(buffer); fill_packet(*packet, test.is_rtp); - LONGS_EQUAL(status::StatusOK, test.composer->compose(*packet)); + CHECK(test.composer->compose(*packet)); UNSIGNED_LONGS_EQUAL(test.reference_size, packet->buffer().size()); for (size_t i = 0; i < test.reference_size; i++) { @@ -198,7 +197,7 @@ void test_parse(const PacketTest& test) { packet->set_buffer(buffer); - LONGS_EQUAL(status::StatusOK, test.parser->parse(*packet, packet->buffer())); + CHECK(test.parser->parse(*packet, packet->buffer())); check_packet(*packet, test.scheme, test.block_length, test.is_rtp); } @@ -210,19 +209,18 @@ void test_compose_parse(const PacketTest& test) { packet::PacketPtr packet1 = packet_factory.new_packet(); CHECK(packet1); - LONGS_EQUAL(status::StatusOK, - test.composer->prepare(*packet1, buffer, Test_payload_size)); + CHECK(test.composer->prepare(*packet1, buffer, Test_payload_size)); packet1->set_buffer(buffer); fill_packet(*packet1, test.is_rtp); - LONGS_EQUAL(status::StatusOK, test.composer->compose(*packet1)); + CHECK(test.composer->compose(*packet1)); packet::PacketPtr packet2 = packet_factory.new_packet(); CHECK(packet2); - LONGS_EQUAL(status::StatusOK, test.parser->parse(*packet2, packet1->buffer())); + CHECK(test.parser->parse(*packet2, packet1->buffer())); check_packet(*packet2, test.scheme, test.block_length, test.is_rtp); } diff --git a/src/tests/roc_fec/test_helpers/packet_dispatcher.h b/src/tests/roc_fec/test_helpers/packet_dispatcher.h index b5e1f0895..8bc07d4cd 100644 --- a/src/tests/roc_fec/test_helpers/packet_dispatcher.h +++ b/src/tests/roc_fec/test_helpers/packet_dispatcher.h @@ -47,7 +47,7 @@ class PacketDispatcher : public packet::IWriter { reset(); } - virtual ROC_NODISCARD status::StatusCode write(const packet::PacketPtr& p) { + virtual ROC_ATTR_NODISCARD status::StatusCode write(const packet::PacketPtr& p) { store_(p); if (++packet_num_ >= num_source_ + num_repair_) { @@ -212,7 +212,9 @@ class PacketDispatcher : public packet::IWriter { FAIL("can't allocate packet"); } - LONGS_EQUAL(status::StatusOK, parser.parse(*pp, old_pp->buffer())); + if (!parser.parse(*pp, old_pp->buffer())) { + FAIL("can't parse packet"); + } pp->set_buffer(old_pp->buffer()); diff --git a/src/tests/roc_fec/test_helpers/status_reader.h b/src/tests/roc_fec/test_helpers/status_reader.h index 9dd730dc6..55f7b0ebe 100644 --- a/src/tests/roc_fec/test_helpers/status_reader.h +++ b/src/tests/roc_fec/test_helpers/status_reader.h @@ -22,8 +22,8 @@ class StatusReader : public packet::IReader { : code_(code) { } - virtual ROC_NODISCARD status::StatusCode read(packet::PacketPtr& pp, - packet::PacketReadMode mode) { + virtual ROC_ATTR_NODISCARD status::StatusCode read(packet::PacketPtr& pp, + packet::PacketReadMode mode) { return code_; } diff --git a/src/tests/roc_fec/test_helpers/status_writer.h b/src/tests/roc_fec/test_helpers/status_writer.h index 0a6d7a3da..86d5fe2e7 100644 --- a/src/tests/roc_fec/test_helpers/status_writer.h +++ b/src/tests/roc_fec/test_helpers/status_writer.h @@ -22,7 +22,7 @@ class StatusWriter : public packet::IWriter { : code_(code) { } - virtual ROC_NODISCARD status::StatusCode write(const packet::PacketPtr&) { + virtual ROC_ATTR_NODISCARD status::StatusCode write(const packet::PacketPtr&) { return code_; } diff --git a/src/tests/roc_netio/test_helpers/conn_reader.h b/src/tests/roc_netio/test_helpers/conn_reader.h index 5953a0975..8939b0196 100644 --- a/src/tests/roc_netio/test_helpers/conn_reader.h +++ b/src/tests/roc_netio/test_helpers/conn_reader.h @@ -9,6 +9,8 @@ #ifndef ROC_NETIO_TEST_HELPERS_CONN_READER_H_ #define ROC_NETIO_TEST_HELPERS_CONN_READER_H_ +#include + #include "roc_core/fast_random.h" #include "roc_core/stddefs.h" #include "roc_core/thread.h" @@ -16,8 +18,6 @@ #include "test_helpers/mock_conn_handler.h" -#include - namespace roc { namespace netio { namespace test { diff --git a/src/tests/roc_netio/test_helpers/conn_writer.h b/src/tests/roc_netio/test_helpers/conn_writer.h index ebf7e60f1..1a8db232b 100644 --- a/src/tests/roc_netio/test_helpers/conn_writer.h +++ b/src/tests/roc_netio/test_helpers/conn_writer.h @@ -9,6 +9,8 @@ #ifndef ROC_NETIO_TEST_HELPERS_CONN_WRITER_H_ #define ROC_NETIO_TEST_HELPERS_CONN_WRITER_H_ +#include + #include "roc_core/fast_random.h" #include "roc_core/stddefs.h" #include "roc_core/thread.h" @@ -17,8 +19,6 @@ #include "test_helpers/mock_conn_handler.h" -#include - namespace roc { namespace netio { namespace test { diff --git a/src/tests/roc_netio/test_resolve.cpp b/src/tests/roc_netio/test_resolve.cpp index 62ea3d126..acce94ded 100644 --- a/src/tests/roc_netio/test_resolve.cpp +++ b/src/tests/roc_netio/test_resolve.cpp @@ -47,7 +47,8 @@ TEST(resolve, ipv4) { LONGS_EQUAL(status::StatusOK, net_loop.init_status()); address::NetworkUri endpoint_uri(arena); - CHECK(address::parse_network_uri("rtp://127.0.0.1:123", endpoint_uri)); + CHECK(address::parse_network_uri("rtp://127.0.0.1:123", + address::NetworkUri::Subset_Full, endpoint_uri)); address::SocketAddr address; CHECK(resolve_endpoint_address(net_loop, endpoint_uri, address)); @@ -61,7 +62,8 @@ TEST(resolve, ipv6) { LONGS_EQUAL(status::StatusOK, net_loop.init_status()); address::NetworkUri endpoint_uri(arena); - CHECK(address::parse_network_uri("rtp://[::1]:123", endpoint_uri)); + CHECK(address::parse_network_uri("rtp://[::1]:123", address::NetworkUri::Subset_Full, + endpoint_uri)); address::SocketAddr address; CHECK(resolve_endpoint_address(net_loop, endpoint_uri, address)); @@ -75,7 +77,8 @@ TEST(resolve, hostname) { LONGS_EQUAL(status::StatusOK, net_loop.init_status()); address::NetworkUri endpoint_uri(arena); - CHECK(address::parse_network_uri("rtp://localhost:123", endpoint_uri)); + CHECK(address::parse_network_uri("rtp://localhost:123", + address::NetworkUri::Subset_Full, endpoint_uri)); address::SocketAddr address; CHECK(resolve_endpoint_address(net_loop, endpoint_uri, address)); @@ -95,7 +98,8 @@ TEST(resolve, standard_port) { LONGS_EQUAL(status::StatusOK, net_loop.init_status()); address::NetworkUri endpoint_uri(arena); - CHECK(address::parse_network_uri("rtsp://127.0.0.1", endpoint_uri)); + CHECK(address::parse_network_uri("rtsp://127.0.0.1", address::NetworkUri::Subset_Full, + endpoint_uri)); address::SocketAddr address; CHECK(resolve_endpoint_address(net_loop, endpoint_uri, address)); @@ -109,21 +113,24 @@ TEST(resolve, bad_host) { { // bad ipv4 address::NetworkUri endpoint_uri(arena); - CHECK(address::parse_network_uri("rtp://300.0.0.1:123", endpoint_uri)); + CHECK(address::parse_network_uri("rtp://300.0.0.1:123", + address::NetworkUri::Subset_Full, endpoint_uri)); address::SocketAddr address; CHECK(!resolve_endpoint_address(net_loop, endpoint_uri, address)); } { // bad ipv6 address::NetworkUri endpoint_uri(arena); - CHECK(address::parse_network_uri("rtp://[11::22::]:123", endpoint_uri)); + CHECK(address::parse_network_uri("rtp://[11::22::]:123", + address::NetworkUri::Subset_Full, endpoint_uri)); address::SocketAddr address; CHECK(!resolve_endpoint_address(net_loop, endpoint_uri, address)); } { // bad hostname address::NetworkUri endpoint_uri(arena); - CHECK(address::parse_network_uri("rtp://_:123", endpoint_uri)); + CHECK(address::parse_network_uri("rtp://_:123", address::NetworkUri::Subset_Full, + endpoint_uri)); address::SocketAddr address; CHECK(!resolve_endpoint_address(net_loop, endpoint_uri, address)); diff --git a/src/tests/roc_node/test_receiver.cpp b/src/tests/roc_node/test_receiver.cpp index fd3a8c719..055ea9145 100644 --- a/src/tests/roc_node/test_receiver.cpp +++ b/src/tests/roc_node/test_receiver.cpp @@ -25,8 +25,8 @@ enum { DefaultSlot = 0 }; core::HeapArena arena; void parse_uri(address::NetworkUri& uri, const char* str) { - CHECK(address::parse_network_uri(str, uri)); - CHECK(uri.is_valid()); + CHECK(address::parse_network_uri(str, address::NetworkUri::Subset_Full, uri)); + CHECK(uri.verify(address::NetworkUri::Subset_Full)); } void write_slot_metrics(const pipeline::ReceiverSlotMetrics& slot_metrics, diff --git a/src/tests/roc_node/test_sender.cpp b/src/tests/roc_node/test_sender.cpp index 40434547b..4dd04b3d8 100644 --- a/src/tests/roc_node/test_sender.cpp +++ b/src/tests/roc_node/test_sender.cpp @@ -24,8 +24,8 @@ enum { DefaultSlot = 0 }; core::HeapArena arena; void parse_uri(address::NetworkUri& uri, const char* str) { - CHECK(address::parse_network_uri(str, uri)); - CHECK(uri.is_valid()); + CHECK(address::parse_network_uri(str, address::NetworkUri::Subset_Full, uri)); + CHECK(uri.verify(address::NetworkUri::Subset_Full)); } void write_slot_metrics(const pipeline::SenderSlotMetrics& slot_metrics, void* slot_arg) { diff --git a/src/tests/roc_packet/test_delayed_reader.cpp b/src/tests/roc_packet/test_delayed_reader.cpp index 6fd820e7c..d566ee98f 100644 --- a/src/tests/roc_packet/test_delayed_reader.cpp +++ b/src/tests/roc_packet/test_delayed_reader.cpp @@ -68,7 +68,8 @@ class MockReader : public IReader { : code_(code) { } - virtual ROC_NODISCARD status::StatusCode read(PacketPtr& pp, PacketReadMode mode) { + virtual ROC_ATTR_NODISCARD status::StatusCode read(PacketPtr& pp, + PacketReadMode mode) { return code_; } diff --git a/src/tests/roc_packet/test_interleaver.cpp b/src/tests/roc_packet/test_interleaver.cpp index 2bcd54722..1c3672fca 100644 --- a/src/tests/roc_packet/test_interleaver.cpp +++ b/src/tests/roc_packet/test_interleaver.cpp @@ -43,7 +43,7 @@ class MockWriter : public IWriter, public core::NonCopyable<> { , code_(status::NoStatus) { } - virtual ROC_NODISCARD status::StatusCode write(const PacketPtr& pp) { + virtual ROC_ATTR_NODISCARD status::StatusCode write(const PacketPtr& pp) { ++call_count_; if (code_enabled_) { diff --git a/src/tests/roc_packet/test_shipper.cpp b/src/tests/roc_packet/test_shipper.cpp index d7d2b710a..1901fb30f 100644 --- a/src/tests/roc_packet/test_shipper.cpp +++ b/src/tests/roc_packet/test_shipper.cpp @@ -13,7 +13,6 @@ #include "roc_packet/packet_factory.h" #include "roc_packet/shipper.h" #include "roc_rtp/headers.h" -#include "roc_status/status_code.h" namespace roc { namespace packet { @@ -45,7 +44,7 @@ class MockWriter : public IWriter, public core::NonCopyable<> { : code_(code) { } - virtual ROC_NODISCARD status::StatusCode write(const PacketPtr&) { + virtual ROC_ATTR_NODISCARD status::StatusCode write(const PacketPtr&) { return code_; } @@ -59,27 +58,25 @@ struct MockComposer : public IComposer, public core::NonCopyable<> { , compose_call_count(0) { } - ROC_NODISCARD virtual status::StatusCode init_status() const { + virtual status::StatusCode init_status() const { return status::StatusOK; } - ROC_NODISCARD virtual status::StatusCode - align(core::Slice&, size_t, size_t) { - return status::StatusOK; + virtual bool align(core::Slice&, size_t, size_t) { + return true; } - ROC_NODISCARD virtual status::StatusCode - prepare(Packet&, core::Slice&, size_t) { - return status::StatusOK; + virtual bool prepare(Packet&, core::Slice&, size_t) { + return true; } - ROC_NODISCARD virtual status::StatusCode pad(Packet&, size_t) { - return status::StatusOK; + virtual bool pad(Packet&, size_t) { + return true; } - ROC_NODISCARD virtual status::StatusCode compose(Packet&) { + virtual bool compose(Packet&) { ++compose_call_count; - return status::StatusOK; + return true; } unsigned compose_call_count; diff --git a/src/tests/roc_pipeline/bench_pipeline_loop_contention.cpp b/src/tests/roc_pipeline/bench_pipeline_loop_contention.cpp index 2b262b107..9b9036da3 100644 --- a/src/tests/roc_pipeline/bench_pipeline_loop_contention.cpp +++ b/src/tests/roc_pipeline/bench_pipeline_loop_contention.cpp @@ -8,8 +8,8 @@ #include +#include "roc_core/fast_random.h" #include "roc_core/heap_arena.h" -#include "roc_core/secure_random.h" #include "roc_ctl/control_task_executor.h" #include "roc_ctl/control_task_queue.h" #include "roc_pipeline/pipeline_loop.h" diff --git a/src/tests/roc_pipeline/bench_pipeline_loop_peak_load.cpp b/src/tests/roc_pipeline/bench_pipeline_loop_peak_load.cpp index 2ff00722d..e1b3011d0 100644 --- a/src/tests/roc_pipeline/bench_pipeline_loop_peak_load.cpp +++ b/src/tests/roc_pipeline/bench_pipeline_loop_peak_load.cpp @@ -6,6 +6,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include + #include "roc_core/atomic.h" #include "roc_core/fast_random.h" #include "roc_core/heap_arena.h" @@ -17,8 +19,6 @@ #include "roc_ctl/control_task_queue.h" #include "roc_pipeline/pipeline_loop.h" -#include - namespace roc { namespace pipeline { namespace { diff --git a/src/tests/roc_pipeline/test_helpers/mock_sink.h b/src/tests/roc_pipeline/test_helpers/mock_sink.h index d1694b371..aa0fcec5b 100644 --- a/src/tests/roc_pipeline/test_helpers/mock_sink.h +++ b/src/tests/roc_pipeline/test_helpers/mock_sink.h @@ -81,7 +81,7 @@ class MockSink : public sndio::ISink, public core::NonCopyable<> { return status::StatusOK; } - virtual ROC_NODISCARD status::StatusCode flush() { + virtual ROC_ATTR_NODISCARD status::StatusCode flush() { return status::StatusOK; } diff --git a/src/tests/roc_pipeline/test_helpers/packet_reader.h b/src/tests/roc_pipeline/test_helpers/packet_reader.h index d24aab3f1..c2c92ec43 100644 --- a/src/tests/roc_pipeline/test_helpers/packet_reader.h +++ b/src/tests/roc_pipeline/test_helpers/packet_reader.h @@ -143,7 +143,7 @@ class PacketReader : public core::NonCopyable<> { packet::PacketPtr pp = packet_factory_.new_packet(); CHECK(pp); - LONGS_EQUAL(status::StatusOK, parser_->parse(*pp, bp)); + CHECK(parser_->parse(*pp, bp)); CHECK(pp->flags() & packet::Packet::FlagRTP); if (first_) { diff --git a/src/tests/roc_pipeline/test_helpers/packet_writer.h b/src/tests/roc_pipeline/test_helpers/packet_writer.h index 58f977956..c291bf74c 100644 --- a/src/tests/roc_pipeline/test_helpers/packet_writer.h +++ b/src/tests/roc_pipeline/test_helpers/packet_writer.h @@ -242,10 +242,8 @@ class PacketWriter : public core::NonCopyable<> { core::Slice bp = packet_factory_.new_packet_buffer(); CHECK(bp); - LONGS_EQUAL( - status::StatusOK, - source_composer_->prepare( - *pp, bp, payload_encoder_->encoded_byte_count(samples_per_packet))); + CHECK(source_composer_->prepare( + *pp, bp, payload_encoder_->encoded_byte_count(samples_per_packet))); pp->set_buffer(bp); @@ -292,12 +290,12 @@ class PacketWriter : public core::NonCopyable<> { packet::PacketPtr fp; while (fec_queue_.read(fp, packet::ModeFetch) == status::StatusOK) { if (fp->has_flags(packet::Packet::FlagAudio)) { - LONGS_EQUAL(status::StatusOK, source_composer_->compose(*fp)); + CHECK(source_composer_->compose(*fp)); LONGS_EQUAL( status::StatusOK, source_writer_->write(prepare_for_delivery_(fp, sample_spec))); } else { - LONGS_EQUAL(status::StatusOK, repair_composer_->compose(*fp)); + CHECK(repair_composer_->compose(*fp)); LONGS_EQUAL( status::StatusOK, repair_writer_->write(prepare_for_delivery_(fp, sample_spec))); @@ -305,7 +303,7 @@ class PacketWriter : public core::NonCopyable<> { } } else { // compose and "deliver" packet - LONGS_EQUAL(status::StatusOK, source_composer_->compose(*pp)); + CHECK(source_composer_->compose(*pp)); LONGS_EQUAL(status::StatusOK, source_writer_->write(prepare_for_delivery_(pp, sample_spec))); } diff --git a/src/tests/roc_pipeline/test_state_tracker.cpp b/src/tests/roc_pipeline/test_state_tracker.cpp new file mode 100644 index 000000000..f406fe699 --- /dev/null +++ b/src/tests/roc_pipeline/test_state_tracker.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2023 Roc Streaming authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "test_harness.h" + +#include "roc_address/protocol.h" +#include "roc_audio/mixer.h" +#include "roc_audio/sample.h" +#include "roc_core/atomic.h" +#include "roc_core/heap_arena.h" +#include "roc_core/noop_arena.h" +#include "roc_core/thread.h" +#include "roc_core/time.h" +#include "roc_pipeline/config.h" +#include "roc_pipeline/receiver_endpoint.h" +#include "roc_pipeline/receiver_session_group.h" +#include "roc_core/semaphore.h" + +namespace roc { +namespace pipeline { + +namespace { + +enum { PacketSz = 512 }; + +core::HeapArena arena; + +packet::PacketFactory packet_factory(arena, PacketSz); +audio::FrameFactory frame_factory(arena, PacketSz * sizeof(audio::sample_t)); + +audio::ProcessorMap processor_map(arena); +rtp::EncodingMap encoding_map(arena); + +class TestThread : public core::Thread { +public: + TestThread(StateTracker& st, unsigned int state_mask, core::nanoseconds_t deadline) + : t_(st) + , r_(0) + , state_mask_(state_mask) + , deadline_(deadline) { + } + + bool running() const { + return r_; + } + + void wait_running() { + while (!r_) { + core::sleep_for(core::ClockMonotonic, core::Microsecond); + } + } + +private: + virtual void run() { + r_ = true; + t_.wait_state(state_mask_, deadline_); + r_ = false; + } + + StateTracker& t_; + core::Atomic r_; + unsigned int state_mask_; + core::nanoseconds_t deadline_; +}; + +} // namespace + +TEST_GROUP(state_tracker) {}; + +TEST(state_tracker, simple_timeout) { + StateTracker state_tracker; + TestThread thr(state_tracker, sndio::DeviceState_Active, + core::timestamp(core::ClockMonotonic) + core::Millisecond * 500); + + CHECK(thr.start()); + core::sleep_for(core::ClockMonotonic, core::Millisecond * 1000); + CHECK(!(thr.running())); + thr.join(); +} + +TEST(state_tracker, multiple_timeout) { + StateTracker state_tracker; + TestThread** threads_ptr = new TestThread*[10]; + for (int i = 0; i < 10; i++) { + threads_ptr[i] = + new TestThread(state_tracker, sndio::DeviceState_Active, + core::timestamp(core::ClockMonotonic) + core::Millisecond * 1000); + } + + for (int i = 0; i < 10; i++) { + CHECK(threads_ptr[i]->start()); + } + + roc_log(LogDebug, "started running"); + core::sleep_for(core::ClockMonotonic, core::Millisecond * 2000); + + for (int i = 0; i < 10; i++) { + CHECK(!threads_ptr[i]->running()); + } + + roc_log(LogDebug, "started joining"); + + for (int i = 0; i < 10; i++) { + threads_ptr[i]->join(); + } + + roc_log(LogDebug, "finished joining"); +} + +TEST(state_tracker, multiple_switch) { + StateTracker state_tracker; + TestThread** threads_ptr = new TestThread*[10]; + for (int i = 0; i < 10; i++) { + threads_ptr[i] = new TestThread(state_tracker, sndio::DeviceState_Active, -1); + } + + for (int i = 0; i < 10; i++) { + CHECK(threads_ptr[i]->start()); + } + + roc_log(LogDebug, "started running"); + core::sleep_for(core::ClockMonotonic, core::Millisecond * 500); + + for (int i = 0; i < 10; i++) { + CHECK(threads_ptr[i]->running()); + } + + core::sleep_for(core::ClockMonotonic, core::Millisecond * 500); + state_tracker.register_packet(); + core::sleep_for(core::ClockMonotonic, core::Millisecond * 500); + + for (int i = 0; i < 10; i++) { + CHECK(!(threads_ptr[i]->running())); + } + + roc_log(LogDebug, "started joining"); + for (int i = 0; i < 10; i++) { + threads_ptr[i]->join(); + } + roc_log(LogDebug, "finished joining"); +} + +TEST(state_tracker, semaphore_test) { + core::Semaphore sem(0); + if (sem.timed_wait(1 * core::Second + core::timestamp(core::ClockMonotonic))) + roc_log(LogDebug, "true"); + else + roc_log(LogDebug, "false"); +} +} // namespace pipeline +} // namespace roc diff --git a/src/tests/roc_rtcp/test_communicator.cpp b/src/tests/roc_rtcp/test_communicator.cpp index fe9f7d976..76fd24a92 100644 --- a/src/tests/roc_rtcp/test_communicator.cpp +++ b/src/tests/roc_rtcp/test_communicator.cpp @@ -270,7 +270,7 @@ class MockWriter : public packet::IWriter, public core::NonCopyable<> { , code_(code) { } - virtual ROC_NODISCARD status::StatusCode write(const packet::PacketPtr&) { + virtual ROC_ATTR_NODISCARD status::StatusCode write(const packet::PacketPtr&) { ++call_count_; return code_; } diff --git a/src/tests/roc_rtp/test_helpers/status_reader.h b/src/tests/roc_rtp/test_helpers/status_reader.h index d3df2212c..52bd08c3b 100644 --- a/src/tests/roc_rtp/test_helpers/status_reader.h +++ b/src/tests/roc_rtp/test_helpers/status_reader.h @@ -22,8 +22,8 @@ class StatusReader : public packet::IReader { : code_(code) { } - virtual ROC_NODISCARD status::StatusCode read(packet::PacketPtr& pp, - packet::PacketReadMode mode) { + virtual ROC_ATTR_NODISCARD status::StatusCode read(packet::PacketPtr& pp, + packet::PacketReadMode mode) { return code_; } diff --git a/src/tests/roc_rtp/test_helpers/status_writer.h b/src/tests/roc_rtp/test_helpers/status_writer.h index 9a7e0a65c..d1dedf65e 100644 --- a/src/tests/roc_rtp/test_helpers/status_writer.h +++ b/src/tests/roc_rtp/test_helpers/status_writer.h @@ -22,7 +22,7 @@ class StatusWriter : public packet::IWriter { : code_(code) { } - virtual ROC_NODISCARD status::StatusCode write(const packet::PacketPtr&) { + virtual ROC_ATTR_NODISCARD status::StatusCode write(const packet::PacketPtr&) { return code_; } diff --git a/src/tests/roc_rtp/test_packet_formats.cpp b/src/tests/roc_rtp/test_packet_formats.cpp index a5bc46ed0..4d28343ce 100644 --- a/src/tests/roc_rtp/test_packet_formats.cpp +++ b/src/tests/roc_rtp/test_packet_formats.cpp @@ -166,7 +166,7 @@ void check_parse_decode(const test::PacketInfo& pi) { packet->set_buffer(buffer); Parser parser(NULL, encoding_map, arena); - LONGS_EQUAL(status::StatusOK, parser.parse(*packet, packet->buffer())); + CHECK(parser.parse(*packet, packet->buffer())); const Encoding* encoding = encoding_map.find_by_pt(packet->rtp()->payload_type); CHECK(encoding); @@ -202,18 +202,17 @@ void check_compose_encode(const test::PacketInfo& pi) { Composer composer(NULL, arena); - LONGS_EQUAL(status::StatusOK, - composer.prepare(*packet, buffer, pi.payload_size + pi.padding_size)); + CHECK(composer.prepare(*packet, buffer, pi.payload_size + pi.padding_size)); packet->set_buffer(buffer); encode_samples(*encoder, *packet, pi); set_packet_fields(*packet, pi); if (pi.padding_size != 0) { - LONGS_EQUAL(status::StatusOK, composer.pad(*packet, pi.padding_size)); + composer.pad(*packet, pi.padding_size); } - LONGS_EQUAL(status::StatusOK, composer.compose(*packet)); + CHECK(composer.compose(*packet)); check_format_info(*encoding, pi); check_packet_fields(*packet, pi); diff --git a/src/tests/roc_sndio/test_helpers/mock_sink.h b/src/tests/roc_sndio/test_helpers/mock_sink.h index ca1275853..fbfd042a0 100644 --- a/src/tests/roc_sndio/test_helpers/mock_sink.h +++ b/src/tests/roc_sndio/test_helpers/mock_sink.h @@ -80,7 +80,7 @@ class MockSink : public ISink { return status::StatusOK; } - virtual ROC_NODISCARD status::StatusCode flush() { + virtual ROC_ATTR_NODISCARD status::StatusCode flush() { return status::StatusOK; } diff --git a/src/tools/roc_recv/main.cpp b/src/tools/roc_recv/main.cpp index 91cafc290..70da9886c 100644 --- a/src/tools/roc_recv/main.cpp +++ b/src/tools/roc_recv/main.cpp @@ -497,7 +497,8 @@ bool prepare_receiver(const gengetopt_args_info& args, for (size_t slot = 0; slot < (size_t)args.source_given; slot++) { address::NetworkUri endpoint(context.arena()); - if (!address::parse_network_uri(args.source_arg[slot], endpoint)) { + if (!address::parse_network_uri(args.source_arg[slot], + address::NetworkUri::Subset_Full, endpoint)) { roc_log(LogError, "can't parse --source endpoint: %s", args.source_arg[slot]); return false; } @@ -529,7 +530,8 @@ bool prepare_receiver(const gengetopt_args_info& args, for (size_t slot = 0; slot < (size_t)args.repair_given; slot++) { address::NetworkUri endpoint(context.arena()); - if (!address::parse_network_uri(args.repair_arg[slot], endpoint)) { + if (!address::parse_network_uri(args.repair_arg[slot], + address::NetworkUri::Subset_Full, endpoint)) { roc_log(LogError, "can't parse --repair endpoint: %s", args.source_arg[slot]); return false; } @@ -561,7 +563,8 @@ bool prepare_receiver(const gengetopt_args_info& args, for (size_t slot = 0; slot < (size_t)args.control_given; slot++) { address::NetworkUri endpoint(context.arena()); - if (!address::parse_network_uri(args.control_arg[slot], endpoint)) { + if (!address::parse_network_uri(args.control_arg[slot], + address::NetworkUri::Subset_Full, endpoint)) { roc_log(LogError, "can't parse --control endpoint: %s", args.control_arg[slot]); return false; diff --git a/src/tools/roc_send/main.cpp b/src/tools/roc_send/main.cpp index 4a3d6100a..f759efebe 100644 --- a/src/tools/roc_send/main.cpp +++ b/src/tools/roc_send/main.cpp @@ -163,7 +163,8 @@ bool build_sender_config(const gengetopt_args_info& args, } } else if (args.source_given) { address::NetworkUri source_endpoint(context.arena()); - if (!address::parse_network_uri(args.source_arg[0], source_endpoint)) { + if (!address::parse_network_uri( + args.source_arg[0], address::NetworkUri::Subset_Full, source_endpoint)) { roc_log(LogError, "can't parse --source endpoint: %s", args.source_arg[0]); return false; } @@ -446,7 +447,9 @@ bool prepare_sender(const gengetopt_args_info& args, for (size_t slot = 0; slot < (size_t)args.source_given; slot++) { address::NetworkUri source_endpoint(context.arena()); - if (!address::parse_network_uri(args.source_arg[slot], source_endpoint)) { + if (!address::parse_network_uri(args.source_arg[slot], + address::NetworkUri::Subset_Full, + source_endpoint)) { roc_log(LogError, "can't parse --source endpoint: %s", args.source_arg[slot]); return false; } @@ -477,7 +480,9 @@ bool prepare_sender(const gengetopt_args_info& args, for (size_t slot = 0; slot < (size_t)args.repair_given; slot++) { address::NetworkUri repair_endpoint(context.arena()); - if (!address::parse_network_uri(args.repair_arg[slot], repair_endpoint)) { + if (!address::parse_network_uri(args.repair_arg[slot], + address::NetworkUri::Subset_Full, + repair_endpoint)) { roc_log(LogError, "can't parse --repair endpoint: %s", args.repair_arg[slot]); return false; } @@ -498,7 +503,9 @@ bool prepare_sender(const gengetopt_args_info& args, for (size_t slot = 0; slot < (size_t)args.control_given; slot++) { address::NetworkUri control_endpoint(context.arena()); - if (!address::parse_network_uri(args.control_arg[slot], control_endpoint)) { + if (!address::parse_network_uri(args.control_arg[slot], + address::NetworkUri::Subset_Full, + control_endpoint)) { roc_log(LogError, "can't parse --control endpoint: %s", args.control_arg[slot]); return false;