diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..d397d37 Binary files /dev/null and b/.DS_Store differ diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..e49bfad --- /dev/null +++ b/.clang-format @@ -0,0 +1,303 @@ +#****************************************************************************** +#* Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * +#* * +#* See the NOTICE file(s) distributed with this work for additional * +#* information regarding copyright ownership. * +#* * +#* This program and the accompanying materials are made available under the * +#* terms of the Eclipse Public License 2.0 which is available at * +#* http://www.eclipse.org/legal/epl-2.0 * +#* * +#* SPDX-License-Identifier: EPL-2.0 * +#******************************************************************************/ + +#http://clang.llvm.org/docs/ClangFormatStyleOptions.html + +# The style used for all options not specifically set in the configuration. +# This option is supported only in the clang-format configuration (both within +# -style='{...}' and the .clang-format file). +# LLVM A style complying with the LLVM coding standards +# Google A style complying with Google’s C++ style guide +# Chromium A style complying with Chromium’s style guide +# Mozilla A style complying with Mozilla’s style guide +# WebKit A style complying with WebKit’s style guide +BasedOnStyle: Webkit + +# The extra indent or outdent of access modifiers, e.g. public:. +AccessModifierOffset: -4 + +# If true, horizontally aligns arguments after an open bracket. +# This applies to round brackets (parentheses), angle brackets and square +# brackets. This will result in formattings like code +# someLongFunction(argument1, argument2); endcode +AlignAfterOpenBracket: AlwaysBreak + +# If true, aligns escaped newlines as far left as possible. Otherwise puts them +# into the right-most column. +#AlignEscapedNewlinesLeft + +# If true, horizontally align operands of binary and ternary expressions. +AlignOperands: true + +# If true, aligns trailing comments. +AlignTrailingComments: true + +# Allow putting all parameters of a function declaration onto the next line even +# if BinPackParameters is false. +AllowAllParametersOfDeclarationOnNextLine: true + +# Allows contracting simple braced statements to a single line. +# E.g., this allows if (a) { return; } to be put on a single line. +AllowShortBlocksOnASingleLine: false + +# If true, short case labels will be contracted to a single line. +AllowShortCaseLabelsOnASingleLine: false + +# Dependent on the value, int f() { return 0; } can be put on a single line. +# SFS_None (in configuration: None) Never merge functions into a single line. +# SFS_Inline (in configuration: Inline) Only merge functions defined inside a +# class. +# SFS_Empty (in configuration: Empty) Only merge empty functions. +# SFS_All (in configuration: All) Merge all functions fitting on a single line. +AllowShortFunctionsOnASingleLine: None + +# If true, if (a) return; can be put on a single line. +#AllowShortIfStatementsOnASingleLine: false + +# If true, while (true) continue; can be put on a single line. +AllowShortLoopsOnASingleLine: true + +# If true, always break after function definition return types. +# More truthfully called ‘break before the identifier following the type in a +# function definition’. +# PenaltyReturnTypeOnItsOwnLine becomes irrelevant. +AlwaysBreakAfterDefinitionReturnType: All + +# If true, always break before multiline string literals. +AlwaysBreakBeforeMultilineStrings: false + +# If true, always break after the template<...> of a template declaration. +AlwaysBreakTemplateDeclarations: true + +# If false, a function call’s arguments will either be all on the same line or +# will have one line each. +BinPackArguments: false + +# If false, a function call’s arguments will either be all +# on the same line or will have one line each. +BinPackParameters: false + +# The way to wrap binary operators. +# BOS_None (in configuration: None) Break after operators. +# BOS_NonAssignment (in configuration: NonAssignment) Break before operators +# that aren’t assignments. +# BOS_All (in configuration: All) Break before operators. +#BreakBeforeBinaryOperators: None + +# The brace breaking style to use. +# BS_Attach (in configuration: Attach) Always attach braces to surrounding +# context. +# BS_Linux (in configuration: Linux) Like Attach, but break before braces on +# function, namespace and class definitions. +# BS_Stroustrup (in configuration: Stroustrup) Like Attach, but break before +# function definitions, and ‘else’. +# BS_Allman (in configuration: Allman) Always break before braces. +# BS_GNU (in configuration: GNU) Always break before braces and add an extra +# level of indentation to braces of control statements, not to those of class, +# function or other definitions. +BreakBeforeBraces: WebKit + +# If true, ternary operators will be placed after line breaks. +BreakBeforeTernaryOperators: true + +# Always break constructor initializers before commas and align the commas with +# the colon. +BreakConstructorInitializersBeforeComma: true + +# The column limit. +# A column limit of 0 means that there is no column limit. In this case, +# clang-format will respect the input’s line breaking decisions within +# statements unless they contradict other rules. +ColumnLimit: 80 + +# A regular expression that describes comments with special meaning, which +# should not be split into lines or otherwise changed. +CommentPragmas: "\/*(.*)*\/" + +# If the constructor initializers don’t fit on a line, put each initializer on +# its own line. +#ConstructorInitializerAllOnOneLineOrOnePerLine: false + +# The number of characters to use for indentation of constructor initializer +# lists. +ConstructorInitializerIndentWidth: 0 + +# Indent width for line continuations. +#ContinuationIndentWidth: 4 + +# If true, format braced lists as best suited for C++11 braced lists. +# Important differences: - No spaces inside the braced list. - No line break +# before the closing brace. - Indentation with the continuation indent, not with +# the block indent. +# Fundamentally, C++11 braced lists are formatted exactly like function calls +# would be formatted in their place. If the braced list follows a name (e.g. a +# type or variable name), clang-format formats as if the {} were the parentheses +# of a function call with that name. If there is no name, a zero-length name is +# assumed. +Cpp11BracedListStyle: true + +# If true, analyze the formatted file for the most common alignment of & and *. +# Point +#DerivePointerAlignment: false + +# Disables formatting at all. +#DisableFormat: false + +# If true, clang-format detects whether function calls and definitions are +# formatted with one parameter per line. +# Each call can be bin-packed, one-per-line or inconclusive. If it is +# inconclusive, e.g. completely on one line, but a decision needs to be made, +# clang-format analyzes whether there are other bin-packed cases in the input +# file and act accordingly. +# NOTE: This is an experimental flag, that might go away or be renamed. Do not +# use this in config files, etc. Use at your own risk. +ExperimentalAutoDetectBinPacking: false + +# A vector of macros that should be interpreted as foreach loops instead of as +# function calls. +# These are expected to be macros of the form: code +# FOREACH(, ...) endcode +# For example: BOOST_FOREACH. +#ForEachMacros (std::vector) + +# Indent case labels one level from the switch statement. +# When false, use the same indentation level as for the switch statement. Switch +# statement body is always indented one level more than case labels. +IndentCaseLabels: false + +# The number of columns to use for indentation. +IndentWidth: 4 + +# Indent if a function definition or declaration is wrapped after the type. +#IndentWrappedFunctionNames: false + +# If true, empty lines at the start of blocks are kept. +KeepEmptyLinesAtTheStartOfBlocks: false + +# Language, this format style is targeted at. +# LK_None (in configuration: None) Do not use. +# LK_Cpp (in configuration: Cpp) Should be used for C, C++, ObjectiveC, +# ObjectiveC++. +# LK_Java (in configuration: Java) Should be used for Java. +# LK_JavaScript (in configuration: JavaScript) Should be used for JavaScript. +# LK_Proto (in configuration: Proto) Should be used for Protocol Buffers +# (https://developers.google.com/protocol-buffers/). +Language: Cpp + +# The maximum number of consecutive empty lines to keep. +#MaxEmptyLinesToKeep: 0 + +# The indentation used for namespaces. +# NI_None (in configuration: None) Don’t indent in namespaces. +# NI_Inner (in configuration: Inner) Indent only in inner namespaces (nested in +# other namespaces). +# NI_All (in configuration: All) Indent in all namespaces. +NamespaceIndentation: None + +# The number of characters to use for indentation of ObjC blocks. +#ObjCBlockIndentWidth: 4 + +# Add a space after @property in Objective-C, i.e. use \@property (readonly) +# instead of \@property(readonly). +#ObjCSpaceAfterProperty: false + +# Add a space in front of an Objective-C protocol list, i.e. use Foo +# instead of Foo. +#ObjCSpaceBeforeProtocolList: false + +# The penalty for breaking a function call after “call(”. +#PenaltyBreakBeforeFirstCallParameter (unsigned) + +# The penalty for each line break introduced inside a comment. +#PenaltyBreakComment (unsigned) + +# The penalty for breaking before the first <<. +#PenaltyBreakFirstLessLess (unsigned) + +# The penalty for each line break introduced inside a string literal. +#PenaltyBreakString (unsigned) + +# The penalty for each character outside of the column limit. +#PenaltyExcessCharacter (unsigned) + +# Penalty for putting the return type of a function onto its own line. +#PenaltyReturnTypeOnItsOwnLine (unsigned) + +# If true, analyze the formatted file for the most common alignment of & and *. +# PointerAlignment is then used only as fallback. +PointerAlignment: Left + +# If true, a space may be inserted after C style casts. +SpaceAfterCStyleCast: false + +# If false, spaces will be removed before assignment operators. +SpaceBeforeAssignmentOperators: true + +# Defines in which cases to put a space before opening parentheses. +# SBPO_Never (in configuration: Never) Never put a space before opening +# parentheses. +# SBPO_ControlStatements (in configuration: ControlStatements) Put a space +# before opening parentheses only after control statement keywords +# (for/if/while...). +# SBPO_Always (in configuration: Always) Always put a space before opening +# parentheses, except when it’s prohibited by the syntax rules (in function-like +# macro definitions) or when determined by other style rules (after unary +# operators, opening parentheses, etc.) +SpaceBeforeParens: ControlStatements + +# If true, spaces may be inserted into ‘()’. +SpaceInEmptyParentheses: false + +# The number of spaces before trailing line comments (// - comments). +# This does not affect trailing block comments (/**/ - comments) as those +# commonly have different usage patterns and a number of special cases. +SpacesBeforeTrailingComments: 2 + +# If true, spaces will be inserted after ‘<’ and before ‘>’ in template argument +# lists +SpacesInAngles: false + +# If true, spaces may be inserted into C style casts. +SpacesInCStyleCastParentheses: false + +# If true, spaces are inserted inside container literals (e.g. ObjC and +# Javascript array and dict literals). +SpacesInContainerLiterals: false + +# If true, spaces will be inserted after ‘(‘ and before ‘)’. +SpacesInParentheses: false + +# If true, spaces will be inserted after ‘[‘ and before ‘]’. +SpacesInSquareBrackets: false + +# Format compatible with this standard, e.g. use A > instead of A> +# for LS_Cpp03. +# LS_Cpp03 (in configuration: Cpp03) Use C++03-compatible syntax. +# LS_Cpp11 (in configuration: Cpp11) Use features of C++11 (e.g. A> +# instead of A >). +# LS_Auto (in configuration: Auto) Automatic detection based on the input. +Standard: Cpp11 + +# The number of columns used for tab stops. +TabWidth: 4 + +# The way to use tab characters in the resulting file. +# UT_Never (in configuration: Never) Never use tab. +# UT_ForIndentation (in configuration: ForIndentation) Use tabs only for +# indentation. +# UT_Always (in configuration: Always) Use tabs whenever we need to fill +# whitespace that spans at least from one tab stop to the next one. +UseTab: Never + +# Indent code enclosed in an extern block +IndentExternBlock: NoIndent diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..748be04 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,17 @@ +#****************************************************************************** +#* Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * +#* * +#* See the NOTICE file(s) distributed with this work for additional * +#* information regarding copyright ownership. * +#* * +#* This program and the accompanying materials are made available under the * +#* terms of the Eclipse Public License 2.0 which is available at * +#* http://www.eclipse.org/legal/epl-2.0 * +#* * +#* SPDX-License-Identifier: EPL-2.0 * +#******************************************************************************/ + +Checks: '-checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus*' +WarningsAsErrors: true +HeaderFilterRegex: '.*' +FormatStyle: webkit diff --git a/.cppcheck.suppress b/.cppcheck.suppress new file mode 100644 index 0000000..5b0cc3f --- /dev/null +++ b/.cppcheck.suppress @@ -0,0 +1,18 @@ +#****************************************************************************** +#* Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * +#* * +#* See the NOTICE file(s) distributed with this work for additional * +#* information regarding copyright ownership. * +#* * +#* This program and the accompanying materials are made available under the * +#* terms of the Eclipse Public License 2.0 which is available at * +#* http://www.eclipse.org/legal/epl-2.0 * +#* * +#* SPDX-License-Identifier: EPL-2.0 * +#******************************************************************************/ + +cstyleCast +#missingIncludeSystem +missingInclude +unusedStructMember +accessMoved diff --git a/.github/.DS_Store b/.github/.DS_Store new file mode 100644 index 0000000..ca44b90 Binary files /dev/null and b/.github/.DS_Store differ diff --git a/.github/scripts/check_version.sh b/.github/scripts/check_version.sh index e776a4e..ea0c841 100644 --- a/.github/scripts/check_version.sh +++ b/.github/scripts/check_version.sh @@ -32,4 +32,4 @@ fi echo "PROJECT_VERSION=$version" >> $GITHUB_ENV -echo "Retained PROJECT_VERSION=$version" \ No newline at end of file +echo "Retained PROJECT_VERSION=$version" diff --git a/.github/scripts/patch_doxyfile.sh b/.github/scripts/patch_doxyfile.sh index 65d38f3..a6d5e9f 100644 --- a/.github/scripts/patch_doxyfile.sh +++ b/.github/scripts/patch_doxyfile.sh @@ -6,4 +6,4 @@ sed -i "s/%PROJECT_VERSION%/$project_version/g" ./.github/doxygen/Doxyfile project_name="$(head -n 1 README.md | sed 's/#//')" -sed -i "s/%PROJECT_NAME%/$project_name/g" ./.github/doxygen/Doxyfile \ No newline at end of file +sed -i "s/%PROJECT_NAME%/$project_name/g" ./.github/doxygen/Doxyfile diff --git a/.github/scripts/prepare_doxygen.sh b/.github/scripts/prepare_doxygen.sh index 543d953..f87b122 100644 --- a/.github/scripts/prepare_doxygen.sh +++ b/.github/scripts/prepare_doxygen.sh @@ -36,6 +36,3 @@ sed -i "2s/.*/title: $project_name/" _config.yml cd .. echo "Local docs update finished." - - - diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 0000000..11bfc96 --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,50 @@ +name: Build and test code + +on: + push: + branches: + - main + pull_request: + +jobs: + build: + + strategy: + matrix: + env: + - toolchain: "toolchain/gcc-linux.cmake" + runner: ubuntu-latest + generator: "" + - toolchain: "toolchain/clang-macos.cmake" + runner: macos-latest + generator: "" + - toolchain: "\"toolchain/clang-windows.cmake\"" + runner: windows-latest + generator: "-G \"Visual Studio 17 2022\"" + + runs-on: ${{ matrix.env.runner }} + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Install Linux reqs + if: ${{ matrix.env.runner == 'ubuntu-latest' }} + run: | + sudo apt-get update + sudo apt-get install -y clang cmake cppcheck clang-format clang-tidy gcc pre-commit + + - name: Install macOS reqs + if: ${{ matrix.env.runner == 'macos-latest' }} + run: | + brew install llvm cmake cppcheck clang-format gcc pre-commit + + - name: Build + run: | + cmake ${{ matrix.env.generator }} -B build -S . -DCMAKE_TOOLCHAIN_FILE=${{ matrix.env.toolchain }} + cmake --build build -j8 + + - name: Run Linux/macOS tests + if: ${{ matrix.env.runner == 'ubuntu-latest' || matrix.env.runner == 'macos-latest' }} + run: | + ./build/bin/keypleutilcpplib_ut diff --git a/.github/workflows/publish-doc-release.yml b/.github/workflows/publish-doc-release.yml index 5c65148..16c1211 100644 --- a/.github/workflows/publish-doc-release.yml +++ b/.github/workflows/publish-doc-release.yml @@ -38,4 +38,4 @@ jobs: git commit -m "docs: update ${{ github.event.inputs.version || github.ref_name }} documentation" git push origin doc --force env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/publish-doc-snapshot.yml b/.github/workflows/publish-doc-snapshot.yml index 55afb9a..a5f2f41 100644 --- a/.github/workflows/publish-doc-snapshot.yml +++ b/.github/workflows/publish-doc-snapshot.yml @@ -41,4 +41,4 @@ jobs: git diff --quiet && git diff --staged --quiet || git commit -m "docs: update snapshot documentation" git push origin doc --force env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..176a839 --- /dev/null +++ b/.gitignore @@ -0,0 +1,52 @@ +#****************************************************************************** +#* Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * +#* * +#* See the NOTICE file(s) distributed with this work for additional * +#* information regarding copyright ownership. * +#* * +#* This program and the accompanying materials are made available under the * +#* terms of the Eclipse Public License 2.0 which is available at * +#* http://www.eclipse.org/legal/epl-2.0 * +#* * +#* SPDX-License-Identifier: EPL-2.0 * +#******************************************************************************/ + +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Build directories +build +out + +# IDE files +CMakeSettings.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..f3aad16 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,54 @@ +#****************************************************************************** +#* Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * +#* * +#* See the NOTICE file(s) distributed with this work for additional * +#* information regarding copyright ownership. * +#* * +#* This program and the accompanying materials are made available under the * +#* terms of the Eclipse Public License 2.0 which is available at * +#* http://www.eclipse.org/legal/epl-2.0 * +#* * +#* SPDX-License-Identifier: EPL-2.0 * +#******************************************************************************/ +#**************************************************************************************************/ + +fail_fast: false + +repos: + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] + + - repo: https://github.com/pocc/pre-commit-hooks + rev: master + hooks: + - id: clang-tidy + name: clang-tidy + entry: clang-tidy -p=build + --system-headers + --fix-errors + + # Code formatting (see .clang-format for config used). + - id: clang-format + name: clang-format + args: [-i] + + # Static code analysis (for C++ files). + - id: cppcheck + name: cppcheck + args: [--enable=all, + --inline-suppr, + --error-exitcode=1, + --language=c++, + --std=c++11, + --suppressions-list=./.cppcheck.suppress] + files: \.(cpp|hpp)$ + + # Coding style analysis. Based on Google C++ code style. + # cpplint configuration can be found in CPPLINT.cfg. + - id: cpplint diff --git a/CMakeLists.txt b/CMakeLists.txt index 33857fb..cef0af9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,29 +1,30 @@ -# ************************************************************************************************* -# Copyright (c) 2023 Calypso Networks Association https://calypsonet.org/ * -# * -# See the NOTICE file(s) distributed with this work for additional information regarding * -# copyright ownership. * -# * -# This program and the accompanying materials are made available under the terms of the Eclipse * -# Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * -# * -# SPDX-License-Identifier: EPL-2.0 * -# *************************************************************************************************/ - -PROJECT(KeypleUtil C CXX) -CMAKE_MINIMUM_REQUIRED(VERSION 3.0) +#****************************************************************************** +#* Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * +#* * +#* See the NOTICE file(s) distributed with this work for additional * +#* information regarding copyright ownership. * +#* * +#* This program and the accompanying materials are made available under the * +#* terms of the Eclipse Public License 2.0 which is available at * +#* http://www.eclipse.org/legal/epl-2.0 * +#* * +#* SPDX-License-Identifier: EPL-2.0 * +#******************************************************************************/ + +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) +PROJECT(KeypleUtilCppLib + VERSION 2.4.0 + LANGUAGES C CXX) SET(CMAKE_PROJECT_VERSION_MAJOR "2") -SET(CMAKE_PROJECT_VERSION_MINOR "3") +SET(CMAKE_PROJECT_VERSION_MINOR "4") SET(CMAKE_PROJECT_VERSION_PATCH "0") -SET(CMAKE_PROJECT_VERSION_TWEAK "5") SET(CMAKE_PROJECT_VERSION "${CMAKE_PROJECT_VERSION_MAJOR}. ${CMAKE_PROJECT_VERSION_MINOR}. - ${CMAKE_PROJECT_VERSION_PATCH}. - ${CMAKE_PROJECT_VERSION_TWEAK}") + ${CMAKE_PROJECT_VERSION_PATCH}") -SET(PACKAGE_NAME "KeypleUtil") +SET(PACKAGE_NAME "keyple-util-cpp-lib") SET(PACKAGE_VERSION ${CMAKE_PROJECT_VERSION}) SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index c347b27..33bd8b6 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -90,4 +90,4 @@ The Eclipse Foundation Board of Directors may amend this Code from time to time This Code was inspired by the [Contributor Covenant](https://www.contributor-covenant.org/), version 1.4, available [here](https://www.contributor-covenant.org/version/1/4/code-of-conduct/). -[^1]: Capitalized terms used herein without definition shall have the meanings assigned to them in the Bylaws. \ No newline at end of file +[^1]: Capitalized terms used herein without definition shall have the meanings assigned to them in the Bylaws. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e99c61c..5052fad 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,38 +2,38 @@ **Welcome to the Eclipse Keyple Community!** -We are thrilled to have you onboard and look forward to your contributions. Whether you're a coder, designer, -documenter, or enthusiast, your involvement is invaluable to us. Here's how you can start contributing to Eclipse +We are thrilled to have you onboard and look forward to your contributions. Whether you're a coder, designer, +documenter, or enthusiast, your involvement is invaluable to us. Here's how you can start contributing to Eclipse Keyple: ## Quick Start 1. **Read the Contribution Guidelines**: Before starting, please visit our detailed contributing guide at the -[Eclipse Keyple Contribution Guide](https://keyple.org/community/contributing/). +[Eclipse Keyple Contribution Guide](https://keyple.org/community/contributing/). This guide covers all the necessary information about contributing to the project. -2. **Join the mailing list**: Connect with other contributors on our -[mailing list](https://accounts.eclipse.org/mailing-list/keyple-dev/). +2. **Join the mailing list**: Connect with other contributors on our +[mailing list](https://accounts.eclipse.org/mailing-list/keyple-dev/). It's a great place to ask questions, share ideas, and collaborate. 3. **Explore Open Issues**: Check out the issues tab in our GitHub repository. ## How to Contribute -- **Code**: Submit pull requests with bug fixes, new features, and improvements. Make sure to follow the code style and +- **Code**: Submit pull requests with bug fixes, new features, and improvements. Make sure to follow the code style and testing guidelines. - **Documentation**: Help us improve our documentation by fixing errors, adding examples, or writing tutorials. -- **Feedback**: Share your experience using Eclipse Keyple. Feedback on usability, features, and your overall experience +- **Feedback**: Share your experience using Eclipse Keyple. Feedback on usability, features, and your overall experience is incredibly valuable. -- **Community Support**: Answer questions on the community forums, help with user support, and participate in +- **Community Support**: Answer questions on the community forums, help with user support, and participate in discussions. ## Need Help? -If you have any questions or need assistance, please reach out on the +If you have any questions or need assistance, please reach out on the [mailing list](https://accounts.eclipse.org/mailing-list/keyple-dev/). --- diff --git a/CPPLINT.cfg b/CPPLINT.cfg new file mode 100644 index 0000000..b8d9efb --- /dev/null +++ b/CPPLINT.cfg @@ -0,0 +1,16 @@ +#****************************************************************************** +#* Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * +#* * +#* See the NOTICE file(s) distributed with this work for additional * +#* information regarding copyright ownership. * +#* * +#* This program and the accompanying materials are made available under the * +#* terms of the Eclipse Public License 2.0 which is available at * +#* http://www.eclipse.org/legal/epl-2.0 * +#* * +#* SPDX-License-Identifier: EPL-2.0 * +#******************************************************************************/ + +set noparent +filter=-whitespace/indent,-build/c++11,-runtime/references,-whitespace/braces,-whitespace/blank_line,-runtime/string +linelength=80 diff --git a/LICENSE b/LICENSE index e55f344..e48e096 100644 --- a/LICENSE +++ b/LICENSE @@ -274,4 +274,4 @@ version(s), and exceptions or additional permissions here}." file in a relevant directory) where a recipient would be likely to look for such a notice. - You may add additional accurate notices of copyright ownership. \ No newline at end of file + You may add additional accurate notices of copyright ownership. diff --git a/NOTICE.md b/NOTICE.md index 87f41d2..4bf020c 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -44,4 +44,4 @@ SPDX-License-Identifier: EPL-2.0 ## Third-party Content -Google Mock/Test. \ No newline at end of file +Google Mock/Test. diff --git a/PUBLISHERS.yml b/PUBLISHERS.yml index a089a31..a6a7061 100644 --- a/PUBLISHERS.yml +++ b/PUBLISHERS.yml @@ -15,4 +15,4 @@ scm: url: https://github.com/eclipe/keyple-utils-cpp-lib ciManagement: system: GitHub Actions - url: https://github.com/eclipe/keyple-utils-cpp-lib/actions \ No newline at end of file + url: https://github.com/eclipe/keyple-utils-cpp-lib/actions diff --git a/SECURITY.md b/SECURITY.md index bfb9250..0b90d27 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,4 +6,4 @@ This project implements the Eclipse Foundation Security Policy ## Reporting a Vulnerability -Please report vulnerabilities to the Eclipse Foundation Security Team at security@eclipse.org \ No newline at end of file +Please report vulnerabilities to the Eclipse Foundation Security Team at security@eclipse.org diff --git a/src/main/ApduUtil.h b/include/keyple/core/util/ApduUtil.hpp similarity index 53% rename from src/main/ApduUtil.h rename to include/keyple/core/util/ApduUtil.hpp index dff387a..b641434 100644 --- a/src/main/ApduUtil.h +++ b/include/keyple/core/util/ApduUtil.hpp @@ -1,22 +1,22 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once #include #include -/* Keyple Core Util */ -#include "KeypleUtilExport.h" +#include "keyple/core/util/KeypleUtilExport.hpp" namespace keyple { namespace core { @@ -30,27 +30,31 @@ namespace util { class KEYPLEUTIL_API ApduUtil final { public: /** - * Builds an APDU request from its elements as defined by the ISO 7816 standard. + * Builds an APDU request from its elements as defined by the ISO 7816 + * standard. * * @param cla The class byte. * @param ins The instruction byte. * @param p1 The parameter 1. * @param p2 The parameter 2. - * @param dataIn The data field of the command (optional). If empty, then LC will be set to 0. - * @param le The maximum number of bytes expected in the data field of the response to the - * command (optional). + * @param dataIn The data field of the command (optional). If empty, then LC + * will be set to 0. + * @param le The maximum number of bytes expected in the data field of the + * response to the command (optional). * @return A byte array containing the resulting apdu command data. * @since 2.0.0 */ - static const std::vector build(const uint8_t cla, - const uint8_t ins, - const uint8_t p1, - const uint8_t p2, - const std::vector& dataIn, - const uint8_t le); + static const std::vector build( + const uint8_t cla, + const uint8_t ins, + const uint8_t p1, + const uint8_t p2, + const std::vector& dataIn, + const uint8_t le); /** - * Builds an APDU request from its elements as defined by the ISO 7816 standard. + * Builds an APDU request from its elements as defined by the ISO 7816 + * standard. * * @param cla The class byte. * @param ins The instruction byte. @@ -60,32 +64,36 @@ class KEYPLEUTIL_API ApduUtil final { * @return A byte array containing the resulting apdu command data. * @since 2.0.0 */ - static const std::vector build(const uint8_t cla, - const uint8_t ins, - const uint8_t p1, - const uint8_t p2, - const std::vector& dataIn); + static const std::vector build( + const uint8_t cla, + const uint8_t ins, + const uint8_t p1, + const uint8_t p2, + const std::vector& dataIn); /** - * Builds an APDU request from its elements as defined by the ISO 7816 standard. + * Builds an APDU request from its elements as defined by the ISO 7816 + * standard. * * @param cla The class byte. * @param ins The instruction byte. * @param p1 The parameter 1. * @param p2 The parameter 2. - * @param le The maximum number of bytes expected in the data field of the response to the command - * (optional). + * @param le The maximum number of bytes expected in the data field of the + * response to the command (optional). * @return A byte array containing the resulting apdu command data. * @since 2.0.0 */ - static const std::vector build(const uint8_t cla, - const uint8_t ins, - const uint8_t p1, - const uint8_t p2, - const uint8_t le); + static const std::vector build( + const uint8_t cla, + const uint8_t ins, + const uint8_t p1, + const uint8_t p2, + const uint8_t le); /** - * Builds an APDU request from its elements as defined by the ISO 7816 standard. + * Builds an APDU request from its elements as defined by the ISO 7816 + * standard. * * @param cla The class byte. * @param ins The instruction byte. @@ -94,33 +102,39 @@ class KEYPLEUTIL_API ApduUtil final { * @return A byte array containing the resulting apdu command data. * @since 2.0.0 */ - static const std::vector build(const uint8_t cla, - const uint8_t ins, - const uint8_t p1, - const uint8_t p2); + static const std::vector build( + const uint8_t cla, + const uint8_t ins, + const uint8_t p1, + const uint8_t p2); /** * (private)
- * Returns a byte array having the expected length according the APDU construction rules. + * Returns a byte array having the expected length according the APDU + * construction rules. * * @param data Data array * @param le Expected outgoing length * @return A new byte array. */ - static std::vector allocateBuffer(const std::vector& data, const uint8_t le); + static std::vector + allocateBuffer(const std::vector& data, const uint8_t le); /** * (private)
- * Returns a byte array having the expected length according the APDU construction rules. + * Returns a byte array having the expected length according the APDU + * construction rules. * * @param data Data array * @return A new byte array. */ - static std::vector allocateBuffer(const std::vector& data); + static std::vector + allocateBuffer(const std::vector& data); /** * (private)
- * Returns a byte array having the expected length according the APDU construction rules. + * Returns a byte array having the expected length according the APDU + * construction rules. * * @param le Expected outgoing length * @return A new byte array. @@ -129,7 +143,8 @@ class KEYPLEUTIL_API ApduUtil final { /** * (private)
- * Returns a byte array having the expected length according the APDU construction rules. + * Returns a byte array having the expected length according the APDU + * construction rules. * * @return A new byte array. */ @@ -138,23 +153,25 @@ class KEYPLEUTIL_API ApduUtil final { /** * Indicates if the provided byte array contains a case4 APDU command. * - *

The ISO7816 case for data in a command-response pair is determined from the provided - * arguments: + *

The ISO7816 case for data in a command-response pair is determined + * from the provided arguments: * *

    - *
  • dataIn  = null, le  = null  →  case 1: - * no command data, no response data expected. - *
  • dataIn  = null, le != null  →  case 2: no - * command data, expected response data. - *
  • dataIn != null, le  = null  →  case 3: - * command data, no response data expected. - *
  • dataIn != null, le  = 0    - *   →  case 4: command data, expected response data. + *
  • dataIn  = null, le  = + * null  →  case 1: no command data, no + * response data expected.
  • dataIn  = null, le != + * null  →  case 2: no command data, expected + * response data.
  • dataIn != null, le  = + * null  →  case 3: command data, no response + * data expected.
  • dataIn != null, le  = + * 0      →  case 4: command + * data, expected response data. *
* * Only the indication for case 4 is retained in the end.
- * In this case (incoming and outgoing data for the card), Le is set to 0, letting the lower - * layer (see API plugin) take care of recovering the exact length of the outgoing data. + * In this case (incoming and outgoing data for the card), Le is set to 0, + * letting the lower layer (see API plugin) take care of recovering the + * exact length of the outgoing data. * * @param apduCommand The apduCommand to check. * @return true the APDU command is case 4. @@ -170,6 +187,6 @@ class KEYPLEUTIL_API ApduUtil final { ApduUtil(); }; -} -} -} +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/BerTlvUtil.h b/include/keyple/core/util/BerTlvUtil.hpp similarity index 62% rename from src/main/BerTlvUtil.h rename to include/keyple/core/util/BerTlvUtil.hpp index 0420e9e..b6b8d2e 100644 --- a/src/main/BerTlvUtil.h +++ b/include/keyple/core/util/BerTlvUtil.hpp @@ -1,23 +1,23 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once +#include #include #include -#include - /* Core */ -#include "KeypleUtilExport.h" +#include "keyple/core/util/KeypleUtilExport.hpp" namespace keyple { namespace core { @@ -26,14 +26,15 @@ namespace util { /** * Helper class to decode BER-TLV encoded data. * - *

This class offers a tradeoff between complexity and efficiency adapted to the TLV structures - * encountered in smart card data, it has the following limitations: + *

This class offers a tradeoff between complexity and efficiency adapted to + * the TLV structures encountered in smart card data, it has the following + * limitations: * *

    *
  • The tag ID fields must not exceed 3 bytes. *
  • The length fields must not exceed 3 bytes. - *
  • Tags present several times in the same TLV structure require special attention (see {@link - * #parseSimple(byte[], boolean)}). + *
  • Tags present several times in the same TLV structure require special + * attention (see {@link #parseSimple(byte[], boolean)}). *
* * @since 2.0.0 @@ -41,38 +42,43 @@ namespace util { class KEYPLEUTIL_API BerTlvUtil { public: /** - * Parse the provided TLV structure and place all or only primitive tags found in a map. The key - * is an integer representing the tag ID (e.g. 0x84 for the DF name tag), the value is the tag - * value as an array of bytes. + * Parse the provided TLV structure and place all or only primitive tags + * found in a map. The key is an integer representing the tag ID (e.g. 0x84 + * for the DF name tag), the value is the tag value as an array of bytes. * - *

Note:This method of extracting tags is deliberately simplified.
- * If the provided TLV structure contains several identical tags then only one will be reported - * in the returned map.
- * To overcome this limitation it is recommended to re-parse the constructed tags known to - * contain other tags. + *

Note:This method of extracting tags is deliberately + * simplified.
If the provided TLV structure contains several identical + * tags then only one will be reported in the returned map.
To overcome + * this limitation it is recommended to re-parse the constructed tags known + * to contain other tags. * * @param tlvStructure The input TLV structure. - * @param primitiveOnly True if only primitives tags are to be placed in the map. + * @param primitiveOnly True if only primitives tags are to be placed in the + * map. * @return A not null map. - * @throw IllegalArgumentException If the parsing of the provided structure failed. + * @throw IllegalArgumentException If the parsing of the provided structure + * failed. * @since 2.0.0 */ static const std::map> parseSimple( const std::vector& tlvStructure, const bool primitiveOnly); /** - * Parse the provided TLV structure and place all or only primitive tags found in a map. The key - * is an integer representing the tag ID (e.g. 0x84 for the DF name tag), the value is the list - * of tag values as a list of arrays of bytes. + * Parse the provided TLV structure and place all or only primitive tags + * found in a map. The key is an integer representing the tag ID (e.g. 0x84 + * for the DF name tag), the value is the list of tag values as a list of + * arrays of bytes. * * @param tlvStructure The input TLV structure. - * @param primitiveOnly True if only primitives tags are to be placed in the map. + * @param primitiveOnly True if only primitives tags are to be placed in the + * map. * @return A not null map. - * @throw IllegalArgumentException If the parsing of the provided structure failed. + * @throw IllegalArgumentException If the parsing of the provided structure + * failed. * @since 2.1.0 */ - static const std::map>> parse( - const std::vector& tlvStructure, const bool primitiveOnly); + static const std::map>> + parse(const std::vector& tlvStructure, const bool primitiveOnly); /** * Indicates if the provided tag ID corresponds to a constructed tag. @@ -92,39 +98,44 @@ class KEYPLEUTIL_API BerTlvUtil { /** * (private)
- * Parse the provided TLV structure from the provided offset and place all or only primitive tags - * found in a map. + * Parse the provided TLV structure from the provided offset and place all + * or only primitive tags found in a map. * * @param tlvStructure The input TLV structure. - * @param primitiveOnly True if only primitives tags are to be placed in the map. + * @param primitiveOnly True if only primitives tags are to be placed in the + * map. * @return A not null map. */ - static const std::map> parseBufferSimple( + static const std::map> + parseBufferSimple( const std::vector& tlvStructure, const bool primitiveOnly); /** - * (private)
- * Parse the provided TLV structure from the provided offset and place all or only primitive - * tags found in a map. - * - * @param tlvStructure The input TLV structure. - * @param primitiveOnly True if only primitives tags are to be placed in the map. - * @return A not null map. - */ - static const std::map>> parseBuffer( + * (private)
+ * Parse the provided TLV structure from the provided offset and place all + * or only primitive tags found in a map. + * + * @param tlvStructure The input TLV structure. + * @param primitiveOnly True if only primitives tags are to be placed in the + * map. + * @return A not null map. + */ + static const std::map>> + parseBuffer( const std::vector& tlvStructure, const bool primitiveOnly); /** * (private)
- * Gets a reference to the values of the existing tag in the map, or put the new tag in the map - * with an empty list of values. + * Gets a reference to the values of the existing tag in the map, or put the + * new tag in the map with an empty list of values. * * @param tlvs The map. * @param tag The TAG. * @return A not null reference to the associated list of values. */ static std::vector>& getOrInitTagValues( - std::map>>& tlvs, const int tag); + std::map>>& tlvs, + const int tag); /** * (private)
@@ -134,22 +145,29 @@ class KEYPLEUTIL_API BerTlvUtil { * @param offset The starting offset in the structure. * @return An int. * @throw IllegalArgumentException If the tag field is invalid. - * @throw IndexOutOfBoundsException If offset is out of range for the provided tlvStructure. + * @throw IndexOutOfBoundsException If offset is out of range for the + * provided tlvStructure. */ - static int getTagSize(const std::vector& tlvStructure, const int offset); + static int + getTagSize(const std::vector& tlvStructure, const int offset); /** * (private)
- * Gets, as an integer, the tag of the provided size present at the designated location. + * Gets, as an integer, the tag of the provided size present at the + * designated location. * * @param tlvStructure The input TLV structure. * @param offset The starting offset in the structure. * @param size The tag size. * @return An int representing the tag value. * @throw IllegalArgumentException If the size is wrong. - * @throw IndexOutOfBoundsException If offset is out of range for the provided tlvStructure. + * @throw IndexOutOfBoundsException If offset is out of range for the + * provided tlvStructure. */ - static int getTag(const std::vector& tlvStructure, const int offset, const int size); + static int getTag( + const std::vector& tlvStructure, + const int offset, + const int size); /** * (private)
@@ -159,26 +177,31 @@ class KEYPLEUTIL_API BerTlvUtil { * @param offset The starting offset in the structure. * @return An int between 1 and 3. * @throw IllegalArgumentException If the length field is invalid. - * @throw IndexOutOfBoundsException If offset is out of range for the provided tlvStructure. + * @throw IndexOutOfBoundsException If offset is out of range for the + * provided tlvStructure. */ - static int getLengthSize(const std::vector& tlvStructure, const int offset); + static int + getLengthSize(const std::vector& tlvStructure, const int offset); /** * (private)
- * Gets, as an integer, the length of the provided size present at the designated location. + * Gets, as an integer, the length of the provided size present at the + * designated location. * * @param tlvStructure The input TLV structure. * @param offset The starting offset in the structure. * @param size The tag size. * @return An int representing the length value. * @throw IllegalArgumentException If the size is wrong. - * @throw IndexOutOfBoundsException If offset is out of range for the provided tlvStructure. + * @throw IndexOutOfBoundsException If offset is out of range for the + * provided tlvStructure. */ - static int getLength(const std::vector& tlvStructure, - const int offset, - const int size); + static int getLength( + const std::vector& tlvStructure, + const int offset, + const int size); }; -} -} -} +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/ByteArrayUtil.h b/include/keyple/core/util/ByteArrayUtil.hpp similarity index 60% rename from src/main/ByteArrayUtil.h rename to include/keyple/core/util/ByteArrayUtil.hpp index 89a5b24..4a43fba 100644 --- a/src/main/ByteArrayUtil.h +++ b/include/keyple/core/util/ByteArrayUtil.hpp @@ -1,14 +1,15 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once @@ -18,11 +19,8 @@ #include #include -/* Util */ -#include "Pattern.h" - -/* Core */ -#include "KeypleUtilExport.h" +#include "keyple/core/util/KeypleUtilExport.hpp" +#include "keyple/core/util/cpp/Pattern.hpp" namespace keyple { namespace core { @@ -33,27 +31,31 @@ namespace util { */ class KEYPLEUTIL_API ByteArrayUtil { public: - /** - * Extracts "nbBytes" bytes from the "bitOffset" index (in bits) from a byte array. + /** + * Extracts "nbBytes" bytes from the "bitOffset" index (in bits) from a + * byte array. * * @param src The source byte array. * @param bitOffset The offset (in bits). * @param nbBytes The number of bytes to extract. * @return A not null byte array. - * @throws ArrayIndexOutOfBoundsException If "bitOffset" or "nbBytes" is out of range. + * @throws ArrayIndexOutOfBoundsException If "bitOffset" or "nbBytes" is out + * of range. * @throws NegativeArraySizeException If "nbBytes" is negative. * @since 2.1.0 */ - static const std::vector extractBytes(const std::vector& src, - const int bitOffset, - const int nbBytes); + static const std::vector extractBytes( + const std::vector& src, + const int bitOffset, + const int nbBytes); - /** + /** * Extracts the least significant bytes (LSB) of a number into a byte array. * - *

Caution: the result may be erroneous if the number of bytes to extract is greater than the - * number of bytes associated to the input number (e.g. 2 bytes max for a "short", 4 bytes max - * for an "integer" or 8 bytes max for a "long"). + *

Caution: the result may be erroneous if the number of bytes to extract + * is greater than the number of bytes associated to the input number (e.g. + * 2 bytes max for a "short", 4 bytes max for an "integer" or 8 bytes max + * for a "long"). * * @param src The source. * @param nbBytes The number of bytes to extract. @@ -61,93 +63,109 @@ class KEYPLEUTIL_API ByteArrayUtil { * @throw NegativeArraySizeException If "nbBytes" is negative. * @since 2.3.0 */ - static const std::vector extractBytes(const uint64_t src, const int nbBytes); + static const std::vector + extractBytes(const uint64_t src, const int nbBytes); /** - * Extracts a 2-byte "short" located at a specific "offset" in a source byte array. + * Extracts a 2-byte "short" located at a specific "offset" in a source byte + * array. * * @param src The source byte array. * @param offset The offset (in bytes). * @return A short. - * @throw ArrayIndexOutOfBoundsException If "offset" is not in range [0..(src.length-2)] + * @throw ArrayIndexOutOfBoundsException If "offset" is not in range + * [0..(src.length-2)] * @since 2.3.0 */ - static uint16_t extractShort(const std::vector& src, const int offset); + static uint16_t + extractShort(const std::vector& src, const int offset); /** - * Converts "nbBytes" bytes located at the "offset" provided in a source byte array into an - * "integer". + * Converts "nbBytes" bytes located at the "offset" provided in a source + * byte array into an "integer". * - *

Caution: the result may be erroneous if "nbBytes" is not in range [1..4]. + *

Caution: the result may be erroneous if "nbBytes" is not in range + * [1..4]. * * @param src The source byte array. * @param offset The offset (in bytes). * @param nbBytes The number of bytes to extract. - * @param isSigned True if the resulting integer is "signed" (relevant only if "nbBytes" is in - * range [1..3]). + * @param isSigned True if the resulting integer is "signed" (relevant only + * if "nbBytes" is in range [1..3]). * @return An int. - * @throws ArrayIndexOutOfBoundsException If "offset" is not in range [0..(src.length-nbBytes)] + * @throws ArrayIndexOutOfBoundsException If "offset" is not in range + * [0..(src.length-nbBytes)] * @since 2.1.0 */ - static uint32_t extractInt(const std::vector& src, - const int offset, - const int nbBytes, - const bool isSigned); + static uint32_t extractInt( + const std::vector& src, + const int offset, + const int nbBytes, + const bool isSigned); /** - * Converts "nbBytes" bytes located at the "offset" provided in a source byte array into a - * "long". + * Converts "nbBytes" bytes located at the "offset" provided in a source + * byte array into a "long". * - *

Caution: the result may be erroneous if "nbBytes" is not in range [1..8]. + *

Caution: the result may be erroneous if "nbBytes" is not in range + * [1..8]. * * @param src The source byte array. * @param offset The offset (in bytes). * @param nbBytes The number of bytes to extract. - * @param isSigned True if the resulting integer is "signed" (relevant only if "nbBytes" is in - * range [1..7]). + * @param isSigned True if the resulting integer is "signed" (relevant only + * if "nbBytes" is in range [1..7]). * @return A long. - * @throw ArrayIndexOutOfBoundsException If "offset" is not in range [0..(src.length-nbBytes)] + * @throw ArrayIndexOutOfBoundsException If "offset" is not in range + * [0..(src.length-nbBytes)] * @since 2.3.0 */ - static uint64_t extractLong(const std::vector& src, - const int offset, - const int nbBytes, - const bool isSigned); + static uint64_t extractLong( + const std::vector& src, + const int offset, + const int nbBytes, + const bool isSigned); /** - * Copy the least significant bytes (LSB) of a number (byte, short, integer or long) into a byte - * array at a specific offset. + * Copy the least significant bytes (LSB) of a number (byte, short, integer + * or long) into a byte array at a specific offset. * * @param src The number. * @param dest The target byte array. * @param offset The offset (in bytes). * @param nbBytes The number of bytes to copy. * @throws NegativeArraySizeException If "nbBytes" is negative. - * @throws ArrayIndexOutOfBoundsException If "offset" is not in range [0..(dest.length-nbBytes)] + * @throws ArrayIndexOutOfBoundsException If "offset" is not in range + * [0..(dest.length-nbBytes)] * @since 2.3.0 */ - static void copyBytes(const uint64_t src, - std::vector& dest, - const int offset, - const int nbBytes); + static void copyBytes( + const uint64_t src, + std::vector& dest, + const int offset, + const int nbBytes); /** - * Checks if the provided string is formed by an even number of hexadecimal digits.
+ * Checks if the provided string is formed by an even number of hexadecimal + * digits.
* *

    *
  • {@code "1234AB"} will match. - *
  • {@code "1234AB2"}, {@code "12 34AB"} or {@code "x1234AB"} won't match. + *
  • {@code "1234AB2"}, {@code "12 34AB"} or {@code "x1234AB"} won't + * match. *
* * @param hex A string. - * @return true if the string matches the expected hexadecimal representation, false otherwise. + * @return true if the string matches the expected hexadecimal + * representation, false otherwise. * @since 2.0.0 * @deprecated Use {@link HexUtil#isValid(String)} method instead. */ static bool isValidHexString(const std::string& hex); /** - * Normalizes the input hex string by padding on the left by a zero if necessary. + * Normalizes the input hex string by padding on the left by a zero if + * necessary. * * @param hex The hex string to normalize. * @return A not null string. @@ -158,16 +176,16 @@ class KEYPLEUTIL_API ByteArrayUtil { static const std::string normalizeHexString(const std::string& hex); /** - * Create a byte array from an hexadecimal string made of consecutive even number of digits in - * the range {0..9,a..f,A..F}. + * Create a byte array from an hexadecimal string made of consecutive even + * number of digits in the range {0..9,a..f,A..F}. * - *

No checks are performed on the input string, except for nullity, zero length and length - * parity. + *

No checks are performed on the input string, except for nullity, zero + * length and length parity. * * @param hex The hexadecimal string to convert. * @return A not empty byte array. - * @throw IllegalArgumentException If the provided string is null, empty or made of an odd - * number of characters. + * @throw IllegalArgumentException If the provided string is null, empty or + * made of an odd number of characters. * @see isValidHexString(const std::string&) * @since 2.0.0 * @deprecated Use HexUtil::toByteArray(const std::string&) method instead. @@ -180,104 +198,115 @@ class KEYPLEUTIL_API ByteArrayUtil { * @param src The byte array to convert. * @return An empty string if the byte array is null or empty. * @since 2.0.0 - * @deprecated Use HexUtil::toHex(const std::vector&) method instead. + * @deprecated Use HexUtil::toHex(const std::vector&) method + * instead. */ static const std::string toHex(const std::vector& src); /** - * Converts 2 bytes located at the offset provided in the byte array into an unsigned - * integer. + * Converts 2 bytes located at the offset provided in the byte array into an + * unsigned integer. * - *

The 2 bytes are assumed to be in the of the most significant byte first order (aka - * 'network order' or 'big-endian' or 'MSB'). + *

The 2 bytes are assumed to be in the of the most significant byte + * first order (aka 'network order' or 'big-endian' or 'MSB'). * * @param bytes A byte array. * @param offset The position of the 2 bytes in the array. * @return A positive int. - * @throw ArrayIndexOutOfBoundsException If "offset" is not in range [0..(bytes.length-2)] + * @throw ArrayIndexOutOfBoundsException If "offset" is not in range + * [0..(bytes.length-2)] * @since 2.0.0 - * @deprecated Use extractInt(const std::vector&, int, int, boolean) method instead - * with "nbBytes = 2" and "isSigned = false". + * @deprecated Use extractInt(const std::vector&, int, int, + * boolean) method instead with "nbBytes = 2" and "isSigned = false". */ - static int twoBytesToInt(const std::vector& bytes, const int offset); + static int + twoBytesToInt(const std::vector& bytes, const int offset); /** - * Converts 2 bytes located at the offset provided in the byte array into a signed - * integer. + * Converts 2 bytes located at the offset provided in the byte array into a + * signed integer. * - *

The 2 bytes are assumed to be in the of the most significant byte first order (aka - * 'network order' or 'big-endian' or 'MSB'). + *

The 2 bytes are assumed to be in the of the most significant byte + * first order (aka 'network order' or 'big-endian' or 'MSB'). * - *

The number is also considered as signed. That is, if the MSB (first left bit) is 1, then - * the number is negative and the conversion is done accordingly with the usual binary - * arithmetic. + *

The number is also considered as signed. That is, if the MSB (first + * left bit) is 1, then the number is negative and the conversion is done + * accordingly with the usual binary arithmetic. * * @param bytes A byte array. * @param offset The position of the 2 bytes in the array. * @return A negative or positive int. - * @throw ArrayIndexOutOfBoundsException If "offset" is not in range [0..(bytes.length-3)] + * @throw ArrayIndexOutOfBoundsException If "offset" is not in range + * [0..(bytes.length-3)] * @since 2.0.0 - * @deprecated Use extractInt(const std::vector&, int, int, boolean) method instead - * with "nbBytes = "2" and "isSigned = true". + * @deprecated Use extractInt(const std::vector&, int, int, + * boolean) method instead with "nbBytes = "2" and "isSigned = true". */ - static int twoBytesSignedToInt(const std::vector& bytes, const int offset); + static int + twoBytesSignedToInt(const std::vector& bytes, const int offset); /** - * Converts 3 bytes located at the offset provided in the byte array into an unsigned - * integer. + * Converts 3 bytes located at the offset provided in the byte array into an + * unsigned integer. * - *

The 3 bytes are assumed to be in the of the most significant byte first order (aka - * 'network order' or 'big-endian' or 'MSB'). + *

The 3 bytes are assumed to be in the of the most significant byte + * first order (aka 'network order' or 'big-endian' or 'MSB'). * * @param bytes A byte array. * @param offset The position of the 3 bytes in the array. * @return A positive int. - * @throw ArrayIndexOutOfBoundsException If "offset" is not in range [0..(bytes.length-3)] + * @throw ArrayIndexOutOfBoundsException If "offset" is not in range + * [0..(bytes.length-3)] * @since 2.0.0 - * @deprecated Use extractInt(const std::vector&, int, int, boolean) method instead - * with "nbBytes = 3" and "isSigned = false". + * @deprecated Use extractInt(const std::vector&, int, int, + * boolean) method instead with "nbBytes = 3" and "isSigned = false". */ - static int threeBytesToInt(const std::vector& bytes, const int offset); + static int + threeBytesToInt(const std::vector& bytes, const int offset); /** - * Converts 3 bytes located at the offset provided in the byte array into an signed - * integer. + * Converts 3 bytes located at the offset provided in the byte array into an + * signed integer. * - *

The 3 bytes are assumed to be in the of the most significant byte first order (aka - * 'network order' or 'big-endian' or 'MSB'). + *

The 3 bytes are assumed to be in the of the most significant byte + * first order (aka 'network order' or 'big-endian' or 'MSB'). * - *

The number is also considered as signed. That is, if the MSB (first left bit) is 1, then - * the number is negative and the conversion is done accordingly with the usual binary - * arithmetic. + *

The number is also considered as signed. That is, if the MSB (first + * left bit) is 1, then the number is negative and the conversion is done + * accordingly with the usual binary arithmetic. * * @param bytes A byte array. * @param offset The position of the 3 bytes in the array. * @return A positive int. - * @throw ArrayIndexOutOfBoundsException If "offset" is not in range [0..(bytes.length-3)] + * @throw ArrayIndexOutOfBoundsException If "offset" is not in range + * [0..(bytes.length-3)] * @since 2.0.0 - * @deprecated Use extractInt(const std::vector&, int, int, boolean) method instead - * with "nbBytes = "3" and "isSigned = true". + * @deprecated Use extractInt(const std::vector&, int, int, + * boolean) method instead with "nbBytes = "3" and "isSigned = true". */ - static int threeBytesSignedToInt(const std::vector& bytes, const int offset); + static int + threeBytesSignedToInt(const std::vector& bytes, const int offset); /** - * Converts 4 bytes located at the offset provided in the byte array into an unsigned - * integer. + * Converts 4 bytes located at the offset provided in the byte array into an + * unsigned integer. * - *

The 4 bytes are assumed to be in the of the most significant byte first order (aka - * 'network order' or 'big-endian' or 'MSB'). + *

The 4 bytes are assumed to be in the of the most significant byte + * first order (aka 'network order' or 'big-endian' or 'MSB'). * * @param bytes A byte array. * @param offset The position of the 4 bytes in the array. * @return A positive int. - * @throw ArrayIndexOutOfBoundsException If "offset" is not in range [0..(bytes.length-3)] + * @throw ArrayIndexOutOfBoundsException If "offset" is not in range + * [0..(bytes.length-3)] * @since 2.0.0 - * @deprecated Use extractInt(const std::vector&, int, int, boolean) method instead - * with "nbBytes = 4" and "isSigned = true|false". + * @deprecated Use extractInt(const std::vector&, int, int, + * boolean) method instead with "nbBytes = 4" and "isSigned = true|false". */ - static int fourBytesToInt(const std::vector& bytes, const int offset); + static int + fourBytesToInt(const std::vector& bytes, const int offset); }; -} -} -} +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/HexUtil.h b/include/keyple/core/util/HexUtil.hpp similarity index 71% rename from src/main/HexUtil.h rename to include/keyple/core/util/HexUtil.hpp index f7bab82..e725578 100644 --- a/src/main/HexUtil.h +++ b/include/keyple/core/util/HexUtil.hpp @@ -1,14 +1,15 @@ -/************************************************************************************************** - * Copyright (c) 2023 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once @@ -16,8 +17,7 @@ #include #include -/* Keyple Core Util */ -#include "KeypleUtilExport.h" +#include "keyple/core/util/KeypleUtilExport.hpp" namespace keyple { namespace core { @@ -30,11 +30,13 @@ class KEYPLEUTIL_API HexUtil final { * *

    *
  • {@code "1234AB"} will match. - *
  • {@code "1234AB2"}, {@code "12 34AB"} or {@code "x1234AB"} won't match. + *
  • {@code "1234AB2"}, {@code "12 34AB"} or {@code "x1234AB"} won't + * match. *
* * @param hex The string to check. - * @return True if the string matches the expected hexadecimal representation, false otherwise. + * @return True if the string matches the expected hexadecimal + * representation, false otherwise. * @since 2.1.0 */ static bool isValid(const std::string& hex); @@ -42,13 +44,13 @@ class KEYPLEUTIL_API HexUtil final { /** * Converts a hexadecimal string to a byte array. * - *

Caution: the result may be erroneous if the string does not contain only hexadecimal - * characters. + *

Caution: the result may be erroneous if the string does not contain + * only hexadecimal characters. * * @param hex The hexadecimal string to convert. * @return An empty byte array if the input string is empty. - * @throw StringIndexOutOfBoundsException If the input string is made of an odd number of - * characters. + * @throw StringIndexOutOfBoundsException If the input string is made of an + * odd number of characters. * @since 2.1.0 */ static const std::vector toByteArray(const std::string& hex); @@ -56,12 +58,12 @@ class KEYPLEUTIL_API HexUtil final { /** * Converts a hexadecimal string to a "byte". * - *

Note: if the hexadecimal string contains more than two characters, then only the last two - * characters will be taken into account. In this case, please note that the conversion - * processing will be less performant. + *

Note: if the hexadecimal string contains more than two characters, + * then only the last two characters will be taken into account. In this + * case, please note that the conversion processing will be less performant. * - *

Caution: the result may be erroneous if the string does not contain only hexadecimal - * characters. + *

Caution: the result may be erroneous if the string does not contain + * only hexadecimal characters. * * @param hex The hexadecimal string to convert. * @return 0 if the input string is empty. @@ -72,12 +74,12 @@ class KEYPLEUTIL_API HexUtil final { /** * Converts a hexadecimal string to a "short". * - *

Note: if the hexadecimal string contains more than four characters, then only the last - * four characters will be taken into account. In this case, please note that the conversion - * processing will be less performant. + *

Note: if the hexadecimal string contains more than four characters, + * then only the last four characters will be taken into account. In this + * case, please note that the conversion processing will be less performant. * - *

Caution: the result may be erroneous if the string does not contain only hexadecimal - * characters. + *

Caution: the result may be erroneous if the string does not contain + * only hexadecimal characters. * * @param hex The hexadecimal string to convert. * @return 0 if the input string is empty. @@ -89,12 +91,12 @@ class KEYPLEUTIL_API HexUtil final { /** * Converts a hexadecimal string to an "integer". * - *

Note: if the hexadecimal string contains more than eight characters, then only the last - * eight characters will be taken into account. In this case, please note that the conversion - * processing will be less performant. + *

Note: if the hexadecimal string contains more than eight characters, + * then only the last eight characters will be taken into account. In this + * case, please note that the conversion processing will be less performant. * - *

Caution: the result may be erroneous if the string does not contain only hexadecimal - * characters. + *

Caution: the result may be erroneous if the string does not contain + * only hexadecimal characters. * * @param hex The hexadecimal string to convert. * @return 0 if the input string is empty. @@ -105,12 +107,12 @@ class KEYPLEUTIL_API HexUtil final { /** * Converts a hexadecimal string to a "long". * - *

Note: if the hexadecimal string contains more than sixteen characters, then only the last - * sixteen characters will be taken into account. In this case, please note that the conversion - * processing will be less performant. + *

Note: if the hexadecimal string contains more than sixteen characters, + * then only the last sixteen characters will be taken into account. In this + * case, please note that the conversion processing will be less performant. * - *

Caution: the result may be erroneous if the string does not contain only hexadecimal - * characters. + *

Caution: the result may be erroneous if the string does not contain + * only hexadecimal characters. * * @param hex The hexadecimal string to convert. * @return 0 if the input string is empty. @@ -139,8 +141,8 @@ class KEYPLEUTIL_API HexUtil final { /** * Converts a "short" to a hexadecimal string. * - *

Note: the returned string has an even length and is left truncated if necessary to keep - * only the significant characters. + *

Note: the returned string has an even length and is left truncated if + * necessary to keep only the significant characters. * * @param val The short to convert. * @return A string containing 2 or 4 characters. @@ -151,8 +153,8 @@ class KEYPLEUTIL_API HexUtil final { /** * Converts an "integer" to a hexadecimal string. * - *

Note: the returned string has an even length and is left truncated if necessary to keep - * only the significant characters. + *

Note: the returned string has an even length and is left truncated if + * necessary to keep only the significant characters. * * @param val The integer to convert. * @return A string containing 2, 4, 6 or 8 characters. @@ -163,8 +165,8 @@ class KEYPLEUTIL_API HexUtil final { /** * Converts a "long" to a hexadecimal string. * - *

Note: the returned string has an even length and is left truncated if necessary to keep - * only the significant characters. + *

Note: the returned string has an even length and is left truncated if + * necessary to keep only the significant characters. * * @param val The long to convert. * @return A string containing 2, 4, 6, 8, 10, 12, 14 or 16 characters. @@ -189,6 +191,6 @@ class KEYPLEUTIL_API HexUtil final { HexUtil(); }; -} -} -} +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/KeypleAssert.h b/include/keyple/core/util/KeypleAssert.hpp similarity index 68% rename from src/main/KeypleAssert.h rename to include/keyple/core/util/KeypleAssert.hpp index b86d1bb..3c10e77 100644 --- a/src/main/KeypleAssert.h +++ b/include/keyple/core/util/KeypleAssert.hpp @@ -1,14 +1,15 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once @@ -16,19 +17,18 @@ #include #include -/* Util */ -#include "KeypleUtilExport.h" -#include "IllegalArgumentException.h" +#include "keyple/core/util/KeypleUtilExport.hpp" +#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp" namespace keyple { namespace core { namespace util { -using namespace keyple::core::util::cpp::exception; +using keyple::core::util::cpp::exception::IllegalArgumentException; /** - * Exposes useful methods for testing method call parameters and raising a IllegalArgumentException - * unchecked exception. + * Exposes useful methods for testing method call parameters and raising a + * IllegalArgumentException unchecked exception. * * @since 2.0.0 */ @@ -51,7 +51,8 @@ class KEYPLEUTIL_API Assert final { * @since 2.0 */ template - Assert& notNull(const std::shared_ptr obj, const std::string& name) + Assert& + notNull(const std::shared_ptr obj, const std::string& name) { if (obj == nullptr) { throw IllegalArgumentException(ARGUMENT + name + IS_NULL); @@ -80,8 +81,9 @@ class KEYPLEUTIL_API Assert final { * @throw IllegalArgumentException if object is null or empty * @since 2.0.0 */ - template - Assert& notEmpty(const std::vector& obj, const std::string& name) + template + Assert& + notEmpty(const std::vector& obj, const std::string& name) { if (obj.empty()) { throw IllegalArgumentException(ARGUMENT + name + IS_EMPTY); @@ -113,16 +115,19 @@ class KEYPLEUTIL_API Assert final { Assert& isTrue(const bool condition, const std::string& name); /** - * Assert that an integer is not null and is greater than or equal to minValue. + * Assert that an integer is not null and is greater than or equal to + * minValue. * * @param number the number to check * @param minValue the min accepted value * @param name the object name * @return the current instance - * @throw IllegalArgumentException if number is null or has a value less than minValue. + * @throw IllegalArgumentException if number is null or has a value less + * than minValue. * @since 2.0.0 */ - Assert& greaterOrEqual(const size_t number, const size_t minValue, const std::string& name); + Assert& greaterOrEqual( + const size_t number, const size_t minValue, const std::string& name); /** * Assert that an integer is equal to value. @@ -131,13 +136,16 @@ class KEYPLEUTIL_API Assert final { * @param value the expected value * @param name the object name * @return the current instance - * @throw IllegalArgumentException if number is null or has a value less than minValue. + * @throw IllegalArgumentException if number is null or has a value less + * than minValue. * @since 2.0.0 */ - Assert& isEqual(const size_t number, const size_t value, const std::string& name); + Assert& + isEqual(const size_t number, const size_t value, const std::string& name); /** - * Assert that an integer is not null and is in the range minValue, maxValue. + * Assert that an integer is not null and is in the range minValue, + * maxValue. * * @param number the number to check * @param minValue the min accepted value @@ -147,10 +155,11 @@ class KEYPLEUTIL_API Assert final { * @throw IllegalArgumentException if number is null or is out of range. * @since 2.0.0 */ - Assert& isInRange(const size_t number, - const size_t minValue, - const size_t maxValue, - const std::string& name); + Assert& isInRange( + const size_t number, + const size_t minValue, + const size_t maxValue, + const std::string& name); /** * Assert that a string has a valid hexadecimal format. @@ -158,8 +167,8 @@ class KEYPLEUTIL_API Assert final { * @param hex The string to check. * @param name The object name. * @return The current instance. - * @throw IllegalArgumentException If the provided string is null, empty or has not a valid - * hexadecimal format. + * @throw IllegalArgumentException If the provided string is null, empty or + * has not a valid hexadecimal format. * @since 2.1.0 */ Assert& isHexString(const std::string& hex, const std::string& name); @@ -168,17 +177,17 @@ class KEYPLEUTIL_API Assert final { /** * */ - static const std::string ARGUMENT; - static const std::string CONDITION; - static const std::string HAS_A_VALUE; - static const std::string LESS_THAN; - static const std::string GREATER_THAN; - static const std::string IS_NULL; - static const std::string IS_EMPTY; - static const std::string IS_FALSE; - static const std::string IS_NOT_HEX; - static const std::string NOT_EQUAL_TO; - static const std::string CLOSING_BRACKET; + static const char* ARGUMENT; + static const char* CONDITION; + static const char* HAS_A_VALUE; + static const char* LESS_THAN; + static const char* GREATER_THAN; + static const char* IS_NULL; + static const char* IS_EMPTY; + static const char* IS_FALSE; + static const char* IS_NOT_HEX; + static const char* NOT_EQUAL_TO; + static const char* CLOSING_BRACKET; /** * Private Constructor @@ -186,6 +195,6 @@ class KEYPLEUTIL_API Assert final { Assert(); }; -} -} -} +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/KeypleUtilExport.h b/include/keyple/core/util/KeypleUtilExport.hpp old mode 100755 new mode 100644 similarity index 54% rename from src/main/KeypleUtilExport.h rename to include/keyple/core/util/KeypleUtilExport.hpp index 3fead7b..0366a88 --- a/src/main/KeypleUtilExport.h +++ b/include/keyple/core/util/KeypleUtilExport.hpp @@ -1,14 +1,15 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once diff --git a/include/keyple/core/util/cpp/Any.hpp b/include/keyple/core/util/cpp/Any.hpp new file mode 100644 index 0000000..a5d21bd --- /dev/null +++ b/include/keyple/core/util/cpp/Any.hpp @@ -0,0 +1,583 @@ +/************************************************************************************************** + * Copyright (c) 2016 Denilson das Mercês Amorim * + * * + * Implementation of N4562 std::experimental::any (merged into C++17) for C++11 + *compilers. * + * * + * See also: * + * + http://en.cppreference.com/w/cpp/any * + * + http://en.cppreference.com/w/cpp/experimental/any * + * + http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#any * + * + https://cplusplus.github.io/LWG/lwg-active.html#2509 * + * * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + ** + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * + **************************************************************************************************/ +#ifndef KEYPLE_CORE_UTIL_ANY_HPP +#define KEYPLE_CORE_UTIL_ANY_HPP +#pragma once +#include +#include +#include +#include +#include + +#if defined(PARTICLE) +#if !defined(__cpp_exceptions) && !defined(ANY_IMPL_NO_EXCEPTIONS) \ + && !defined(ANY_IMPL_EXCEPTIONS) +#define ANY_IMPL_NO_EXCEPTIONS +#endif +#else +// you can opt-out of exceptions by definining ANY_IMPL_NO_EXCEPTIONS, +// but you must ensure not to cast badly when passing an `any' object to +// any_cast(any) +#endif + +#if defined(PARTICLE) +#if !defined(__cpp_rtti) && !defined(ANY_IMPL_NO_RTTI) \ + && !defined(ANY_IMPL_RTTI) +#define ANY_IMPL_NO_RTTI +#endif +#else +// you can opt-out of RTTI by defining ANY_IMPL_NO_RTTI, +// in order to disable functions working with the typeid of a type +#endif + +namespace keyple { +namespace core { +namespace util { +namespace cpp { + +class bad_any_cast : public std::bad_cast { +public: + const char* + what() const noexcept override + { + return "bad any cast"; + } +}; + +class any final { +public: + /// Dummy function to make it virtual + virtual void + dummy() + { + } + + /// Constructs an object of type any with an empty state. + any() + : vtable(nullptr) + { + } + + /// Constructs an object of type any with an equivalent state as other. + any(const any& rhs) + : vtable(rhs.vtable) + { + if (!rhs.empty()) { + rhs.vtable->copy(rhs.storage, this->storage); + } + } + + /// Constructs an object of type any with a state equivalent to the original + /// state of other. rhs is left in a valid but otherwise unspecified state. + any(any&& rhs) noexcept + : vtable(rhs.vtable) + { + if (!rhs.empty()) { + rhs.vtable->move(rhs.storage, this->storage); + rhs.vtable = nullptr; + } + } + + /// Same effect as this->clear(). + ~any() + { + this->clear(); + } + + /// Constructs an object of type any that contains an object of type T + /// direct-initialized with std::forward(value). + /// + /// T shall satisfy the CopyConstructible requirements, otherwise the + /// program is ill-formed. This is because an `any` may be copy constructed + /// into another `any` at any time, so a copy should always be allowed. + template < + typename ValueType, + typename = typename std::enable_if< + !std::is_same::type, any>::value>:: + type> + explicit any(ValueType&& value) + { + static_assert( + std::is_copy_constructible< + typename std::decay::type>::value, + "T shall satisfy the CopyConstructible requirements."); + this->construct(std::forward(value)); + } + + /// Has the same effect as any(rhs).swap(*this). No effects if an exception + /// is thrown. + any& + operator=(const any& rhs) + { + any(rhs).swap(*this); + return *this; + } + + /// Has the same effect as any(std::move(rhs)).swap(*this). + /// + /// The state of *this is equivalent to the original state of rhs and rhs is + /// left in a valid but otherwise unspecified state. + any& + operator=(any&& rhs) noexcept + { + any(std::move(rhs)).swap(*this); + return *this; + } + + /// Has the same effect as any(std::forward(value)).swap(*this) + /// No effect if a exception is thrown. + /// + /// T shall satisfy the CopyConstructible requirements, otherwise the + /// program is ill-formed. This is because an `any` may be copy constructed + /// into another `any` at any time, so a copy should always be allowed. + template < + typename ValueType, + typename = typename std::enable_if< + !std::is_same::type, any>::value>:: + type> + any& + operator=(ValueType&& value) + { + static_assert( + std::is_copy_constructible< + typename std::decay::type>::value, + "T shall satisfy the CopyConstructible requirements."); + any(std::forward(value)).swap(*this); + return *this; + } + + /// If not empty, destroys the contained object. + void + clear() noexcept + { + if (!empty()) { + this->vtable->destroy(storage); + this->vtable = nullptr; + } + } + + /// Returns true if *this has no contained object, otherwise false. + bool + empty() const noexcept + { + return this->vtable == nullptr; + } + +#ifndef ANY_IMPL_NO_RTTI + /// If *this has a contained object of type T, typeid(T); otherwise + /// typeid(void). + const std::type_info& + type() const noexcept + { + return empty() ? typeid(void) : this->vtable->type(); + } +#endif + + /// Exchange the states of *this and rhs. + void + swap(any& rhs) noexcept + { + if (this->vtable != rhs.vtable) { + any tmp(std::move(rhs)); + + // move from *this to rhs. + rhs.vtable = this->vtable; + if (this->vtable != nullptr) { + this->vtable->move(this->storage, rhs.storage); + // this->vtable = nullptr; -- unneeded, see below + } + + // move from tmp (previously rhs) to *this. + this->vtable = tmp.vtable; + if (tmp.vtable != nullptr) { + tmp.vtable->move(tmp.storage, this->storage); + tmp.vtable = nullptr; + } + } else { + if (this->vtable != nullptr) { + this->vtable->swap(this->storage, rhs.storage); + } + } + } + +private: // Storage and Virtual Method Table + union storage_union { + using stack_storage_t = typename std::aligned_storage< + 2 * sizeof(void*), + std::alignment_of::value>::type; + + void* dynamic; + stack_storage_t stack; // 2 words for e.g. shared_ptr + }; + + /// Base VTable specification. + struct vtable_type { + // Note: The caller is responssible for doing .vtable = nullptr after + // destructful operations such as destroy() and/or move(). + +#ifndef ANY_IMPL_NO_RTTI + /// The type of the object this vtable is for. + const std::type_info& (*type)() noexcept; +#endif + + /// Destroys the object in the union. + /// The state of the union after this call is unspecified, caller must + /// ensure not to use src anymore. + void (*destroy)(storage_union&) noexcept; + + /// Copies the **inner** content of the src union into the yet + /// unitialized dest union. As such, both inner objects will have the + /// same state, but on separate memory locations. + void (*copy)(const storage_union& src, storage_union& dest); + + /// Moves the storage from src to the yet unitialized dest union. + /// The state of src after this call is unspecified, caller must ensure + /// not to use src anymore. + void (*move)(storage_union& src, storage_union& dest) noexcept; + + /// Exchanges the storage between lhs and rhs. + void (*swap)(storage_union& lhs, storage_union& rhs) noexcept; + }; + + /// VTable for dynamically allocated storage. + template + struct vtable_dynamic { +#ifndef ANY_IMPL_NO_RTTI + static const std::type_info& + type() noexcept + { + return typeid(T); + } +#endif + + static void + destroy(const storage_union& storage) noexcept + { + // assert(reinterpret_cast(storage.dynamic)); + delete reinterpret_cast(storage.dynamic); + } + + static void + copy(const storage_union& src, storage_union& dest) + { + dest.dynamic = new T(*reinterpret_cast(src.dynamic)); + } + + static void + move(storage_union& src, storage_union& dest) noexcept + { + dest.dynamic = src.dynamic; + src.dynamic = nullptr; + } + + static void + swap(storage_union& lhs, storage_union& rhs) noexcept + { + // just exchage the storage pointers. + std::swap(lhs.dynamic, rhs.dynamic); + } + }; + + /// VTable for stack allocated storage. + template + struct vtable_stack { +#ifndef ANY_IMPL_NO_RTTI + static const std::type_info& + type() noexcept + { + return typeid(T); + } +#endif + + static void + destroy(storage_union& storage) noexcept + { + reinterpret_cast(&storage.stack)->~T(); + } + + static void + copy(const storage_union& src, storage_union& dest) + { + new (&dest.stack) T(reinterpret_cast(src.stack)); + } + + static void + move(storage_union& src, storage_union& dest) noexcept + { + // one of the conditions for using vtable_stack is a nothrow move + // constructor, so this move constructor will never throw a + // exception. + new (&dest.stack) T(std::move(reinterpret_cast(src.stack))); + destroy(src); + } + + static void + swap(storage_union& lhs, storage_union& rhs) noexcept + { + storage_union tmp_storage; + move(rhs, tmp_storage); + move(lhs, rhs); + move(tmp_storage, lhs); + } + }; + + /// Whether the type T must be dynamically allocated or can be stored on the + /// stack. + template + struct requires_allocation + : std::integral_constant< + bool, + !(std::is_nothrow_move_constructible::value // N4562 §6.3/3 + // [any.class] + && sizeof(T) <= sizeof(storage_union::stack) + && std::alignment_of::value <= std::alignment_of< + storage_union::stack_storage_t>::value)> { + }; + + /// Returns the pointer to the vtable of the type T. + template + static vtable_type* + vtable_for_type() + { + using VTableType = typename std::conditional< + requires_allocation::value, + vtable_dynamic, + vtable_stack>::type; + static vtable_type table = { +#ifndef ANY_IMPL_NO_RTTI + VTableType::type, +#endif + VTableType::destroy, + VTableType::copy, + VTableType::move, + VTableType::swap, + }; + return &table; + } + +protected: + template + friend const T* any_cast(const any* operand) noexcept; + template + friend T* any_cast(any* operand) noexcept; + +#ifndef ANY_IMPL_NO_RTTI + /// Same effect as is_same(this->type(), t); + bool + is_typed(const std::type_info& t) const + { + return is_same(this->type(), t); + } +#endif + +#ifndef ANY_IMPL_NO_RTTI + /// Checks if two type infos are the same. + /// + /// If ANY_IMPL_FAST_TYPE_INFO_COMPARE is defined, checks only the address + /// of the type infos, otherwise does an actual comparision. Checking + /// addresses is only a valid approach when there's no interaction with + /// outside sources (other shared libraries and such). + static bool + is_same(const std::type_info& a, const std::type_info& b) + { +#ifdef ANY_IMPL_FAST_TYPE_INFO_COMPARE + return &a == &b; +#else + return a == b; +#endif + } +#endif + + /// Casts (with no type_info checks) the storage pointer as const T*. + template + const T* + cast() const noexcept + { + return requires_allocation::type>::value + ? reinterpret_cast(storage.dynamic) + : reinterpret_cast(&storage.stack); + } + + /// Casts (with no type_info checks) the storage pointer as T*. + template + T* + cast() noexcept + { + return requires_allocation::type>::value + ? reinterpret_cast(storage.dynamic) + : reinterpret_cast(&storage.stack); + } + +private: + storage_union storage = {0}; // on offset(0) so no padding for align + vtable_type* vtable; + + template + typename std::enable_if::value>::type + do_construct(ValueType&& value) + { + storage.dynamic = new T(std::forward(value)); + } + + template + typename std::enable_if::value>::type + do_construct(ValueType&& value) + { + new (&storage.stack) T(std::forward(value)); + } + + /// Chooses between stack and dynamic allocation for the type + /// decay_t, assigns the correct vtable, and constructs the + /// object on our storage. + template + void + construct(ValueType&& value) + { + using T = typename std::decay::type; + + this->vtable = vtable_for_type(); + + do_construct(std::forward(value)); + } +}; + +namespace detail { +template +inline ValueType +any_cast_move_if_true( + typename std::remove_reference::type* p, std::true_type) +{ + return std::move(*p); +} + +template +inline ValueType +any_cast_move_if_true( + typename std::remove_reference::type* p, std::false_type) +{ + return *p; +} +} // namespace detail + +/// Performs *any_cast>>(&operand), or +/// throws bad_any_cast on failure. +template +inline ValueType +any_cast(const any& operand) +{ + auto p = any_cast::type>::type>(&operand); +#ifndef ANY_IMPL_NO_EXCEPTIONS + if (p == nullptr) + throw bad_any_cast(); +#endif + return *p; +} + +/// Performs *any_cast>(&operand), or throws +/// bad_any_cast on failure. +template +inline ValueType +any_cast(any& operand) +{ + auto p + = any_cast::type>(&operand); +#ifndef ANY_IMPL_NO_EXCEPTIONS + if (p == nullptr) + throw bad_any_cast(); +#endif + return *p; +} + +/// +/// If ValueType is MoveConstructible and isn't a lvalue reference, performs +/// std::move(*any_cast>(&operand)), otherwise +/// *any_cast>(&operand). Throws bad_any_cast on +/// failure. +/// +template +inline ValueType +any_cast(any&& operand) +{ + using can_move = std::integral_constant< + bool, + std::is_move_constructible::value + && !std::is_lvalue_reference::value>; + + auto p + = any_cast::type>(&operand); +#ifndef ANY_IMPL_NO_EXCEPTIONS + if (p == nullptr) + throw bad_any_cast(); +#endif + return detail::any_cast_move_if_true(p, can_move()); +} + +/// If operand != nullptr && operand->type() == typeid(ValueType), a pointer to +/// the object contained by operand, otherwise nullptr. +template +inline const ValueType* +any_cast(const any* operand) noexcept +{ + using T = typename std::decay::type; + +#ifndef ANY_IMPL_NO_RTTI + if (operand && operand->is_typed(typeid(T))) +#else + if (operand && operand->vtable == any::vtable_for_type()) +#endif + return operand->cast(); + else + return nullptr; +} + +/// If operand != nullptr && operand->type() == typeid(ValueType), a pointer to +/// the object contained by operand, otherwise nullptr. +template +inline ValueType* +any_cast(any* operand) noexcept +{ + using T = typename std::decay::type; + +#ifndef ANY_IMPL_NO_RTTI + if (operand && operand->is_typed(typeid(T))) +#else + if (operand && operand->vtable == any::vtable_for_type()) +#endif + return operand->cast(); + else + return nullptr; +} + +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ + +namespace std { + +inline void +swap( + keyple::core::util::cpp::any& lhs, + keyple::core::util::cpp::any& rhs) noexcept +{ + lhs.swap(rhs); +} + +} /* namespace std */ + +#endif diff --git a/src/main/cpp/Arrays.h b/include/keyple/core/util/cpp/Arrays.hpp similarity index 53% rename from src/main/cpp/Arrays.h rename to include/keyple/core/util/cpp/Arrays.hpp index 2398809..6948d93 100644 --- a/src/main/cpp/Arrays.h +++ b/include/keyple/core/util/cpp/Arrays.hpp @@ -1,43 +1,46 @@ -/************************************************************************************************** - * Copyright (c) 2023 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once #include +#include +#include #include #include -#include -/* Keyple Core Util */ -#include "IllegalArgumentException.h" -#include "IndexOutOfBoundsException.h" +#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp" +#include "keyple/core/util/cpp/exception/IndexOutOfBoundsException.hpp" namespace keyple { namespace core { namespace util { namespace cpp { -using namespace keyple::core::util::cpp::exception; +using keyple::core::util::cpp::exception::IllegalArgumentException; +using keyple::core::util::cpp::exception::IndexOutOfBoundsException; class Arrays { public: - static bool equals(const std::vector& a1, const std::vector& a2) + static bool + equals(const std::vector& a1, const std::vector& a2) { if (a1.size() != a2.size()) { return false; } for (auto i1 = a1.begin(), i2 = a2.begin(); i1 != a1.end(); - i1++, i2++) { + i1++, i2++) { if (*i1 != *i2) return false; } @@ -45,14 +48,15 @@ class Arrays { return true; } - static bool equals(const std::vector& a1, const std::vector& a2) + static bool + equals(const std::vector& a1, const std::vector& a2) { if (a1.size() != a2.size()) { return false; } for (auto i1 = a1.begin(), i2 = a2.begin(); i1 != a1.end(); - i1++, i2++) { + i1++, i2++) { if (*i1 != *i2) return false; } @@ -60,77 +64,83 @@ class Arrays { return true; } - static int hashCode(const std::vector a) + static int + hashCode(const std::vector& a) { int hash = 0; - for (auto i = a.begin(); i != a.end(); i++) - hash ^= *i; + std::for_each(a.begin(), a.end(), [&](const char i) { hash ^= i; }); return hash; } - static int hashCode(const std::vector a) + static int + hashCode(const std::vector& a) { int hash = 0; - for (auto i = a.begin(); i != a.end(); i++) - hash ^= *i; + std::for_each(a.begin(), a.end(), [&](const uint8_t i) { hash ^= i; }); return hash; } /** - * Copies the specified array, truncating or padding with false (if necessary) so the copy has - * the specified length. + * Copies the specified array, truncating or padding with false (if + * necessary) so the copy has the specified length. */ - static std::vector copyOf(const std::vector& original, const size_t size) + static std::vector + copyOf(const std::vector& original, const size_t size) { std::vector vec; - std::copy(original.begin(), original.begin() + size, std::back_inserter(vec)); + std::copy( + original.begin(), original.begin() + size, std::back_inserter(vec)); return vec; } - static std::vector copyOfRange(const std::vector& original, - const size_t from, - const size_t to) + static std::vector + copyOfRange( + const std::vector& original, const size_t from, const size_t to) { if ((to - from) > original.size()) { throw IndexOutOfBoundsException("index out of bound"); } std::vector vec; - std::copy(original.begin() + from, original.begin() + to, std::back_inserter(vec)); + std::copy( + original.begin() + from, + original.begin() + to, + std::back_inserter(vec)); return vec; } - static std::vector copyOfRange(const std::vector& original, - const size_t from, - const size_t to) + static std::vector + copyOfRange( + const std::vector& original, + const size_t from, + const size_t to) { if (from > original.size()) { - throw IndexOutOfBoundsException("from > original.size()"); } if (from > to) { - throw IllegalArgumentException("from > to"); } std::vector vec; if (to <= original.size()) { - - std::copy(original.begin() + from, original.begin() + to, std::back_inserter(vec)); - + std::copy( + original.begin() + from, + original.begin() + to, + std::back_inserter(vec)); } else { - - std::copy(original.begin() + from, - original.begin() + original.size(), - std::back_inserter(vec)); + std::copy( + original.begin() + from, + original.begin() + original.size(), + std::back_inserter(vec)); vec.resize(to - from, 0); } @@ -138,19 +148,15 @@ class Arrays { } template - static bool contains(const std::vector& a, const T b) + static bool + contains(const std::vector& a, const T b) { - for (const auto& v : a) { - if (v == b) { - return true; - } - } - - return false; + return std::any_of(a.begin(), a.end(), [&](T i) { return i == b; }); } template - static bool containsAll(std::vector a, std::vector b) + static bool + containsAll(std::vector a, std::vector b) { std::sort(a.begin(), a.end()); std::sort(b.begin(), b.end()); @@ -159,29 +165,22 @@ class Arrays { } template - static bool containsOnly(const std::vector& a, const T b) + static bool + containsOnly(const std::vector& a, const T b) { - for (const auto& v : a) { - if (v != b) { - return false; - } - } - - return true; + return std::all_of(a.begin(), a.end(), [&](T i) { return i == b; }); } template - static bool startsWith(const std::vector& a, const std::vector& b) + static bool + startsWith(const std::vector& a, const std::vector& b) { if (b.size() > a.size()) { - return false; } for (size_t i = 0; i < b.size(); i++) { - if (a[i] != b[i]) { - return false; } } @@ -190,19 +189,17 @@ class Arrays { } template - static bool endsWith(const std::vector& a, const std::vector& b) + static bool + endsWith(const std::vector& a, const std::vector& b) { if (b.size() > a.size()) { - return false; } const size_t offset = a.size() - b.size(); for (size_t i = 0; i < b.size(); i++) { - if (a[offset + i] != b[i]) { - return false; } } @@ -211,7 +208,8 @@ class Arrays { } template - static int indexOf(const std::vector& a, const T b) + static int + indexOf(const std::vector& a, const T b) { auto it = std::find(a.begin(), a.end(), b); if (it != a.end()) { @@ -222,50 +220,51 @@ class Arrays { } template - static bool addAll(std::vector& a, const std::vector& b) + static bool + addAll(std::vector& a, const std::vector& b) { if (b.size() == 0) { return false; } - for (const auto& t : b) { - a.push_back(t); - } + std::copy(b.begin(), b.end(), std::back_inserter(a)); return true; } template - static bool addAll(std::vector>& a, const std::vector>& b) + static bool + addAll( + std::vector>& a, + const std::vector>& b) { if (b.size() == 0) { return false; } - for (const auto& t : b) { - a.push_back(t); - } + std::copy(b.begin(), b.end(), std::back_inserter(a)); return true; } - template - static bool addAll(std::vector>& a, const std::vector>& b) + static bool + addAll( + std::vector>& a, + const std::vector>& b) { if (b.size() == 0) { return false; } - for (const auto& u : b) { - a.push_back(std::dynamic_pointer_cast(u)); - } + std::copy(b.begin(), b.end(), std::back_inserter(a)); return true; } template - static void remove(std::vector>& a, const std::shared_ptr& b) + static void + remove(std::vector>& a, const std::shared_ptr& b) { const auto it = std::find(a.begin(), a.end(), b); if (it != a.end()) { @@ -275,7 +274,10 @@ class Arrays { } template - static bool removeAll(std::vector>& a, const std::vector>& b) + static bool + removeAll( + std::vector>& a, + const std::vector>& b) { bool ret = false; @@ -297,7 +299,12 @@ class Arrays { } template - static void fill(std::vector& a, const size_t from_Index, const size_t to_Index, T val) + static void + fill( + std::vector& a, + const size_t from_Index, + const size_t to_Index, + T val) { for (size_t i = from_Index; i < to_Index; i++) { a[i] = val; @@ -305,7 +312,7 @@ class Arrays { } }; -} -} -} -} +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/cpp/Character.h b/include/keyple/core/util/cpp/Character.hpp similarity index 58% rename from src/main/cpp/Character.h rename to include/keyple/core/util/cpp/Character.hpp index c191201..0a150ea 100644 --- a/src/main/cpp/Character.h +++ b/include/keyple/core/util/cpp/Character.hpp @@ -1,14 +1,15 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once @@ -19,7 +20,8 @@ namespace cpp { class Character { public: - static char digit(char ch, int radix) + static char + digit(char ch, int radix) { (void)radix; @@ -36,23 +38,24 @@ class Character { /** * See isWhitespace(). */ - static bool isWhitespace(char c) + static bool + isWhitespace(char c) { - return isWhitespace((int)c); + return isWhitespace(static_cast(c)); } /** * Returns true if the given code point is a Unicode whitespace character. - * The exact set of characters considered as whitespace varies with Unicode version. - * Note that non-breaking spaces are not considered whitespace. - * Note also that line separators are considered whitespace; see isSpaceChar() for an - * alternative. + * The exact set of characters considered as whitespace varies with Unicode + * version. Note that non-breaking spaces are not considered whitespace. + * Note also that line separators are considered whitespace; see + * isSpaceChar() for an alternative. */ - static bool isWhitespace(int codePoint) + static bool + isWhitespace(int codePoint) { - - if ((codePoint >= 0x1c && codePoint <= 0x20) || - (codePoint >= 0x09 && codePoint <= 0x0d)) { + if ((codePoint >= 0x1c && codePoint <= 0x20) + || (codePoint >= 0x09 && codePoint <= 0x0d)) { return true; } if (codePoint < 0x1000) { @@ -67,23 +70,25 @@ class Character { return false; } - /* Exclude General Punctuation's non-breaking spaces (which includes FIGURE SPACE). */ + /* Exclude General Punctuation's non-breaking spaces (which includes + * FIGURE SPACE). */ if (codePoint == 0x2007 || codePoint == 0x202f) { return false; } if (codePoint <= 0xffff) { /* Other whitespace from General Punctuation... */ - return codePoint <= 0x200a || codePoint == 0x2028 || - codePoint == 0x2029 || codePoint == 0x205f || - codePoint == 0x3000; /* ...or CJK Symbols and Punctuation? */ + return codePoint <= 0x200a || codePoint == 0x2028 + || codePoint == 0x2029 || codePoint == 0x205f + || codePoint + == 0x3000; /* ...or CJK Symbols and Punctuation? */ } /* Let icu4c worry about non-BMP code points. */ - //return isWhitespaceImpl(codePoint); + // return isWhitespaceImpl(codePoint); return false; } }; -} -} -} -} +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/KeypleStd.hpp b/include/keyple/core/util/cpp/KeypleStd.hpp new file mode 100644 index 0000000..130e6f4 --- /dev/null +++ b/include/keyple/core/util/cpp/KeypleStd.hpp @@ -0,0 +1,167 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace std { + +// when using a compiler that does not support C++17, define our own +// implementation of reinterpret_pointer_cast +#if !defined(_WIN32) && !(defined(__APPLE__) && defined(__clang__)) \ + && __cplusplus < 201703L +template +inline std::shared_ptr +reinterpret_pointer_cast(std::shared_ptr const& ptr) noexcept +{ + return std::shared_ptr(ptr, reinterpret_cast(ptr.get())); +} +#endif + +inline std::ostream& +operator<<(std::ostream& os, const uint8_t v) +{ + os << static_cast(v) << "(0x" << std::uppercase << std::hex + << std::setfill('0') << std::setw(2) << static_cast(v) << ")"; + + return os; +} + +inline std::ostream& +operator<<(std::ostream& os, const std::vector& v) +{ + for (const auto val : v) { + os << std::uppercase << std::hex << std::setfill('0') << std::setw(2) + << static_cast(val); + } + + return os; +} + +inline std::ostream& +operator<<(std::ostream& os, const std::vector& v) +{ + for (const auto val : v) { + os << std::uppercase << std::hex << std::setfill('0') << std::setw(8) + << static_cast(val); + } + + return os; +} + +inline std::ostream& +operator<<(std::ostream& os, const std::vector& v) +{ + os << "{"; + for (auto it = v.begin(); it != v.end(); ++it) { + if (it != v.begin()) + os << ", "; + os << *it; + } + os << "}"; + + return os; +} + +inline std::ostream& +operator<<(std::ostream& os, const std::set& s) +{ + os << "{"; + for (auto it = s.begin(); it != s.end(); ++it) { + if (it != s.begin()) + os << ", "; + os << *it; + } + os << "}"; + + return os; +} + +template +inline std::ostream& +operator<<(std::ostream& os, const std::map& s) +{ + os << "MAP: {"; + for (auto it = s.begin(); it != s.end(); ++it) { + if (it != s.begin()) + os << ", "; + os << "{" << it->first << ", " << it->second << "}"; + } + os << "}"; + + return os; +} + +template +inline std::ostream& +operator<<(std::ostream& os, const std::map& s) +{ + os << "MAP: {"; + for (auto it = s.begin(); it != s.end(); ++it) { + if (it != s.begin()) + os << ", "; + os << "{" << it->first << ", " << it->second << "}"; + } + os << "}"; + + return os; +} + +template +inline void +split(const std::string& s, const std::regex& re, out result) +{ + std::sregex_token_iterator d(s.begin(), s.end(), re, -1); + std::sregex_token_iterator end; + + while (d != end) { + *result++ = *d++; + } +} + +/* Trim from left */ +inline std::string& +ltrim(std::string& s, const char* t = " \t\n\r\f\v") +{ + s.erase(0, s.find_first_not_of(t)); + + return s; +} + +/* Trim from right */ +inline std::string& +rtrim(std::string& s, const char* t = " \t\n\r\f\v") +{ + s.erase(s.find_last_not_of(t) + 1); + + return s; +} + +/* Trim from left & right */ +inline std::string& +trim(std::string& s, const char* t = " \t\n\r\f\v") +{ + return ltrim(rtrim(s, t), t); +} + +} // namespace std diff --git a/src/main/cpp/Logger.h b/include/keyple/core/util/cpp/Logger.hpp similarity index 67% rename from src/main/cpp/Logger.h rename to include/keyple/core/util/cpp/Logger.hpp index 7b5940f..50b6f26 100644 --- a/src/main/cpp/Logger.h +++ b/include/keyple/core/util/cpp/Logger.hpp @@ -1,36 +1,37 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once +#include #include #include #include #include #include -#include -#include -#include #include +#include #include +#include +#include +#include #include -#include -#ifdef __GNUG__ // gnu C++ compiler +#ifdef __GNUG__ // gnu C++ compiler #include #endif -/* Util */ -#include "KeypleUtilExport.h" +#include "keyple/core/util/KeypleUtilExport.hpp" namespace keyple { namespace core { @@ -70,47 +71,52 @@ class KEYPLEUTIL_API Logger { * */ template - void trace(const std::string& format, Args... args) + void + trace(const std::string& format, Args&&... args) { if (mLevel >= Level::logTrace) log("TRACE", format, std::forward(args)...); } /** - * - */ + * + */ template - void debug(const std::string& format, Args... args) + void + debug(const std::string& format, Args&&... args) { if (mLevel >= Level::logDebug) log("DEBUG", format, std::forward(args)...); } /** - * - */ + * + */ template - void warn(const std::string& format, Args... args) + void + warn(const std::string& format, Args&&... args) { if (mLevel >= Level::logWarn) log("WARN", format, std::forward(args)...); } /** - * - */ + * + */ template - void info(const std::string& format, Args... args) + void + info(const std::string& format, Args&&... args) { if (mLevel >= Level::logInfo) log("INFO", format, std::forward(args)...); } /** - * - */ + * + */ template - void error(const std::string& format, Args... args) + void + error(const std::string& format, Args&&... args) { if (mLevel >= Level::logError) log("ERROR", format, std::forward(args)...); @@ -145,40 +151,47 @@ class KEYPLEUTIL_API Logger { /** * */ -#ifdef __GNUG__ // gnu C++ compiler - std::string demangle(const char* mangled_name) +#ifdef __GNUG__ // gnu C++ compiler + std::string + demangle(const char* mangled_name) { std::size_t len = 0; - int status = 0; + int status = 0; std::unique_ptr ptr( __cxxabiv1::__cxa_demangle(mangled_name, nullptr, &len, &status), &std::free); std::string s(ptr.get()); - if (s.size() > maxClassNameLength) + if (s.size() > maxClassNameLength) { s.resize(maxClassNameLength); + } return s; } #else - std::string demangle(const char* name) + std::string + demangle(const char* name) { std::string s(name); - if (s.size() > maxClassNameLength) + if (s.size() > maxClassNameLength) { s.resize(maxClassNameLength); + } return s; } -#endif // _GNUG_ +#endif // _GNUG_ - void printf(std::ostringstream& os, const char* s) + void + printf(std::ostringstream& os, const char* s) { while (s && *s) { - if (*s == '%' && *(s + 1) != '%') + if (*s == '%' && *(s + 1) != '%') { throw std::runtime_error("invalid format: missing arguments"); + } os << *s++; } } template - void printf(std::ostringstream& os, const char* s, T& value, Args... args) + void + printf(std::ostringstream& os, const char* s, T& value, Args... args) { while (s && *s) { if (*s == '%' && *(s + 1) != '%') { @@ -191,7 +204,8 @@ class KEYPLEUTIL_API Logger { } template - void printf(std::ostringstream& os, const char* s, T* value, Args... args) + void + printf(std::ostringstream& os, const char* s, const T* value, Args... args) { while (s && *s) { if (*s == '%' && *(s + 1) != '%') { @@ -204,21 +218,23 @@ class KEYPLEUTIL_API Logger { } /** - * Because of variadic templates usage, the function must be declared and - * defined in the header file. - */ + * Because of variadic templates usage, the function must be declared and + * defined in the header file. + */ template - void log(const std::string& label, const std::string& format, Args... args) + void + log(const std::string& label, const std::string& format, Args... args) { const std::lock_guard lock(*mtx); /* Header */ std::string name = className; name.resize(70); - std::printf("[%s] [%5s] [%-70s] ", - getCurrentTimestamp().c_str(), - label.c_str(), - name.c_str()); + std::printf( + "[%s] [%5s] [%-70s] ", + getCurrentTimestamp().c_str(), + label.c_str(), + name.c_str()); /* Actual log */ std::ostringstream os; @@ -228,7 +244,7 @@ class KEYPLEUTIL_API Logger { } }; -} -} -} -} +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/cpp/LoggerFactory.h b/include/keyple/core/util/cpp/LoggerFactory.hpp similarity index 58% rename from src/main/cpp/LoggerFactory.h rename to include/keyple/core/util/cpp/LoggerFactory.hpp index 49bdd1e..13dc11d 100644 --- a/src/main/cpp/LoggerFactory.h +++ b/include/keyple/core/util/cpp/LoggerFactory.hpp @@ -1,14 +1,15 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once @@ -17,9 +18,8 @@ #include #include -/* Util */ -#include "KeypleUtilExport.h" -#include "Logger.h" +#include "keyple/core/util/KeypleUtilExport.hpp" +#include "keyple/core/util/cpp/Logger.hpp" namespace keyple { namespace core { @@ -39,7 +39,7 @@ class KEYPLEUTIL_API LoggerFactory { static std::unique_ptr getLogger(const std::type_info& type); }; -} -} -} -} +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/MapUtils.hpp b/include/keyple/core/util/cpp/MapUtils.hpp new file mode 100644 index 0000000..500be14 --- /dev/null +++ b/include/keyple/core/util/cpp/MapUtils.hpp @@ -0,0 +1,54 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +namespace keyple { +namespace core { +namespace util { +namespace cpp { + +class MapUtils { +public: + template + static const std::vector + getKeySet(const std::map& m) + { + std::vector v; + + std::for_each( + m.begin(), m.end(), [&](const auto& e) { v.push_back(e.first); }); + + return v; + } + + template + static const std::vector + getValueSet(const std::map& m) + { + std::vector v; + + std::for_each( + m.begin(), m.end(), [&](const auto& e) { v.push_back(e.second); }); + + return v; + } +}; + +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/Matcher.hpp b/include/keyple/core/util/cpp/Matcher.hpp new file mode 100644 index 0000000..5b41886 --- /dev/null +++ b/include/keyple/core/util/cpp/Matcher.hpp @@ -0,0 +1,252 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include +#include + +#include "keyple/core/util/KeypleUtilExport.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { + +class Pattern; + +class KEYPLEUTIL_API Matcher { +public: + /** + * All matchers have the state used by Pattern during a match. + */ + Matcher(const Pattern* parent, const std::string& text); + + /** + * Initiates a search for an anchored match to a Pattern within the given + * bounds. The groups are filled with default values and the match of the + * root of the state machine is called. The state machine will hold the + * state of the match as it proceeds in this matcher. + */ + bool match(const int from, const int anchor) const; + + /** + * Attempts to match the entire region against the pattern. + * + *

If the match succeeds then more information can be obtained via the + * start, end, and group methods.

+ * + * @return true if, and only if, the entire region sequence matches + * this matcher's pattern + */ + bool matches(); + + /** + * Replaces every subsequence of the input sequence that matches the pattern + * with the given replacement string. + * + *

This method first resets this matcher. It then scans the input + * sequence looking for matches of the pattern. Characters that are not + * part of any match are appended directly to the result string; each match + * is replaced in the result by the replacement string. The replacement + * string may contain references to captured subsequences as in the + * appendReplacement() method. + * + *

Note that backslashes (\\) and dollar signs ($) in + * the replacement string may cause the results to be different than if it + * were being treated as a literal replacement string. Dollar signs may be + * treated as references to captured subsequences as described above, and + * backslashes are used to escape literal characters in the replacement + * string. + * + *

Given the regular expression a*b, the input + * "aabfooaabfooabfoob", and the replacement string "-", an + * invocation of this method on a matcher for that expression would yield + * the + * string "-foo-foo-foo-". + * + *

Invoking this method changes this matcher's state. If the matcher is + * to be used in further matching operations then it should first be reset. + *

+ * + * @param replacement The replacement string + * @return The string constructed by replacing each matching subsequence by + * the replacement string, substituting captured subsequences as needed + */ + std::string replaceAll(const std::string& replacement) const; + + /** + * Attempts to find the next subsequence of the input sequence that matches + * the pattern. + * + * This method starts at the beginning of this matcher's region, o, if a + * previous invocation of the method was successful and the matcher has not + * since been reset, at the first character not matched by the previous + * match. + * + * If the match succeeds then more information can be obtained viw the + * start, end, group methods. + * + * @return true if, and only if, a subsequence of the input sequences + * matches this matcher's patern. + */ + bool find(); + + /** + * Resets this matcher and then attempts to find the next subsequence of the + * input sequence that matches the pattern, starting at the specified index. + * + * If the match succeeds then more information can be obtained viw the + * start, end, group methods, and subsequent invocations of the find() + * method will start at the first character not matched by this match. + * + * @return true if, and only if, a subsequence of the input sequences + * matches this matcher's patern. + * @throw IndexOutOfBoundException if start is less than zero of if start is + * greated than the length of the input sequence. + */ + bool find(const int start); + + /** + * Returns the text that matched a given group of the regular expression. + * Explicit capturing groups in the pattern are numbered left to right in + * order of their opening parenthesis, starting at 1. The special group 0 + * represents the entire match (as if the entier pattern is surrounded by an + * implicit capturing group). + * + * For example, "a((b)c)" matching "abc" would give the following groups: + * 0 "abc" + * 1 "bc" + * 2 "b" + * + * An optional capturing group that failed to match as part of an overall + * sucessful match (for example "a(b)?c" matching "ac") returns null. A + * capturing group that matched the empty string (for example, "a(b?)c" + * matching "ac") returns the empty string. + * + * @throw IllegalStateException if no successful match has been made + */ + const std::string group(const int group) const; + + /** + * Returns the text that matched the whole regular expression. + * + * @return the text + * + * @throw IllegalStateException if no successful match has been made + */ + const std::string group() const; + + /** + * Initiates a search to find a Pattern within the given bounds. The groups + * are filled with defaults values and the match of the root of the state + * machine is called. The state machine will hold the state of the match as + * it proceeds in this matcher. + * + * Matcher.from is not set here, because it is the 'hard' boundary of the + * start of the search which anchors will set to. The from param is the + * 'soft' boundary of the start of the search, meaning that the regex tries + * to match at that index but won't match there. Subsequent calls to the + * search methods start at a new 'soft' boundary which is the end of the + * previous match. + */ + bool search(const int from); + + /** + * Returns the end index of the text. + * + * @return the index after the last charaecter in the text + */ + int getTextLength() const; + + /** + * Resets this matcher. + * + *

Resetting a matcher discards all of its explicit states information + * and sets its append position to zero. The matcher's region is set to the + * default region, which is its entire character sequence. The anchoring and + * transparency of this matcher's region boundaries are unaffected. + */ + Matcher* reset(); + +private: + /** + * The Pattern object that created this Matcher. + */ + const Pattern* mParentPattern; + + /** + * The original string being matched. + */ + const std::string mText; + + /** + * The range within the sequence that is to be matched. Anchors will match + * at these "hard" boundaries. Changing the region changes these values. + */ + int mFrom; + int mTo; + + /** + * Matcher state used by the last node. NOANCHOR is used when a match does + * not have to consume all of the input. ENDANCHOR is the mode used for + * matching all the input. + */ + int ENDANCHOR = 1; + + /** + * The range of string that last matched the pattern. If the last match + * failed then first is -1; last initially holds 0 then it holds the index + * of the end of the last match (which is where the next search starts). + */ + int mFirst = -1, mLast = 0; + + /** + * The end index of what matched in the last match operation. + */ + int mOldLast = -1; + + /** + * Substring on which the regex_search is applied. It used to be a temp + * variable whithin the Matcher::search() function but for some reasons, on + * Windows, the 'groups' std::smatch doesn't keep its data after leaving the + * Matcher::search() function (e.g. in other words, it's very probable that + * std::match only provides references to specific locations in an existing + * string). + */ + std::string mSubs; + + /** + * The storage used by groups. They may contain invalid values if a group + * was skipped during the matching. + */ + std::smatch mGroups; + + /** + * The index of the last position appended in the substitution. + */ + int mLastAppendPosition = 0; + + /** + * Storage used by nodes to tell what repetition they are on in a pattern, + * and where groups begin. The nodes themselves are stateless, so they rely + * on this field to hold state during a match. + */ + std::vector mLocals; +}; + +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/Pattern.hpp b/include/keyple/core/util/cpp/Pattern.hpp new file mode 100644 index 0000000..b2f9b66 --- /dev/null +++ b/include/keyple/core/util/cpp/Pattern.hpp @@ -0,0 +1,70 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/KeypleUtilExport.hpp" +#include "keyple/core/util/cpp/Matcher.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { + +class KEYPLEUTIL_API Pattern { +public: + /** + * + */ + const std::regex mPattern; + + /** + * Constructor + */ + Pattern(const std::string& pattern, const int flags); + + /** + * Returns a compiled form of the given regular expression, as modified by + * the given flags. + * + * @throws PatternSyntexException + */ + std::shared_ptr + compile(const std::string& regularExpression, const int flags) const; + + /** + * Equivalent to Pattern::compile(pattern, 0) + */ + static std::shared_ptr compile(const std::string& pattern); + + /* + * Returns a Matcher for this pattern applied to the given input. The + * Matcher can be used to match the Pattern against the whole input, find + * occurences of the Pattern in the input, or replace parts of the input. + */ + std::shared_ptr matcher(const std::string& input) const; + +private: + /** + * + */ + const int mFlags; +}; + +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/cpp/StringBuilder.h b/include/keyple/core/util/cpp/StringBuilder.hpp old mode 100755 new mode 100644 similarity index 54% rename from src/main/cpp/StringBuilder.h rename to include/keyple/core/util/cpp/StringBuilder.hpp index 46c0c30..a4a037d --- a/src/main/cpp/StringBuilder.h +++ b/include/keyple/core/util/cpp/StringBuilder.hpp @@ -1,19 +1,20 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once -#include #include +#include namespace keyple { namespace core { @@ -25,85 +26,104 @@ class StringBuilder { std::string privateString; public: - StringBuilder() {} + StringBuilder() + { + } - explicit StringBuilder(const std::string& initialString) : privateString(initialString) {} + explicit StringBuilder(const std::string& initialString) + : privateString(initialString) + { + } explicit StringBuilder(std::size_t capacity) { ensureCapacity(capacity); } - char charAt(std::size_t index) + char + charAt(std::size_t index) { return privateString[index]; } - StringBuilder* append(const std::string& toAppend) + StringBuilder* + append(const std::string& toAppend) { privateString += toAppend; return this; } - template StringBuilder* append(const T& toAppend) + template + StringBuilder* + append(const T& toAppend) { privateString += toString(toAppend); return this; } - StringBuilder* insert(std::size_t position, const std::string& toInsert) + StringBuilder* + insert(std::size_t position, const std::string& toInsert) { privateString.insert(position, toInsert); return this; } template - StringBuilder* insert(std::size_t position, const T& toInsert) + StringBuilder* + insert(std::size_t position, const T& toInsert) { privateString.insert(position, toString(toInsert)); return this; } - std::string toString() + const std::string& + toString() { return privateString; } - std::size_t length() + std::size_t + length() { return privateString.length(); } - void setLength(std::size_t newLength) + void + setLength(std::size_t newLength) { privateString.resize(newLength); } - std::size_t capacity() + std::size_t + capacity() { return privateString.capacity(); } - void ensureCapacity(std::size_t minimumCapacity) + void + ensureCapacity(std::size_t minimumCapacity) { privateString.reserve(minimumCapacity); } - StringBuilder* remove(std::size_t start, std::size_t end) + StringBuilder* + remove(std::size_t start, std::size_t end) { privateString.erase(start, end - start); return this; } - StringBuilder* replace(std::size_t start, std::size_t end, - const std::string& newString) + StringBuilder* + replace(std::size_t start, std::size_t end, const std::string& newString) { privateString.replace(start, end - start, newString); return this; } private: - template static std::string toString(const T& subject) + template + static std::string + toString(const T& subject) { std::ostringstream ss; ss << subject; @@ -111,7 +131,7 @@ class StringBuilder { } }; -} -} -} -} +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/StringUtils.hpp b/include/keyple/core/util/cpp/StringUtils.hpp new file mode 100644 index 0000000..4f7495a --- /dev/null +++ b/include/keyple/core/util/cpp/StringUtils.hpp @@ -0,0 +1,115 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "keyple/core/util/cpp/exception/PatternSyntaxException.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { + +using keyple::core::util::cpp::exception::PatternSyntaxException; + +class StringUtils { +public: + static inline const std::string + format(const char* format, ...) + { + char buf[1024]; + va_list args; + + va_start(args, format); + vsnprintf(buf, sizeof(buf), format, args); + va_end(args); + + return buf; + } + + static inline bool + contains(const std::string& s1, const std::string& s2) + { + return s1.find(s2) != std::string::npos; + } + + static inline bool + matches(const std::string& s, const std::string& regex) + { + try { + std::regex r(regex); + return std::regex_match(s, r); + + } catch (const std::regex_error& e) { + throw PatternSyntaxException(e.what()); + } + } + + static inline const std::vector + split(const std::string& s, const std::string& delimiter) + { + std::vector tokens; + std::string _s = s; + + size_t pos = 0; + + while ((pos = _s.find(delimiter)) != std::string::npos) { + tokens.push_back(_s.substr(0, pos)); + _s.erase(0, pos + delimiter.length()); + } + + return tokens; + } + + static inline const std::string + tolower(const std::string& s) + { + std::string copy = s; + std::transform( + copy.begin(), copy.end(), copy.begin(), [](unsigned char c) { + return static_cast(std::tolower(c)); + }); + + return copy; + } + + static inline const std::string + toupper(const std::string& s) + { + std::string copy = s; + std::transform( + copy.begin(), copy.end(), copy.begin(), [](unsigned char c) { + return static_cast(std::toupper(c)); + }); + + return copy; + } + + static inline bool + startsWith(const std::string& s, const std::string& start) + { + return s.rfind(start, 0) == 0; + } +}; + +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/cpp/System.h b/include/keyple/core/util/cpp/System.hpp similarity index 53% rename from src/main/cpp/System.h rename to include/keyple/core/util/cpp/System.hpp index e7cd553..280f24f 100644 --- a/src/main/cpp/System.h +++ b/include/keyple/core/util/cpp/System.hpp @@ -1,49 +1,50 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once #include -#include #include +#include #if defined(_WIN32) #include #endif -/* Keyple Core Util */ -#include "ArrayIndexOutOfBoundsException.h" +#include "keyple/core/util/cpp/exception/ArrayIndexOutOfBoundsException.hpp" namespace keyple { namespace core { namespace util { namespace cpp { -using namespace keyple::core::util::cpp::exception; +using keyple::core::util::cpp::exception::ArrayIndexOutOfBoundsException; class System { public: /** * */ - static unsigned long long nanoTime() + static uint64_t + nanoTime() { #if defined(WIN32) SYSTEMTIME time; GetSystemTime(&time); - return static_cast((time.wHour * 3600 * 1000 + - time.wMinute * 60 * 1000 + - time.wSecond * 1000 + - time.wMilliseconds) * pow(10, 6)); + return static_cast( + (time.wHour * 3600 * 1000 + time.wMinute * 60 * 1000 + + time.wSecond * 1000 + time.wMilliseconds) + * pow(10, 6)); #else timespec ts; // clock_gettime(CLOCK_MONOTONIC, &ts); // Works on FreeBSD @@ -55,8 +56,13 @@ class System { /** * */ - static void arraycopy(const std::vector& src, size_t srcPos, - std::vector& dest, size_t destPos, size_t length) + static void + arraycopy( + const std::vector& src, + size_t srcPos, + std::vector& dest, + size_t destPos, + size_t length) { for (size_t i = 0; i < length; i++) { dest[destPos + i] = src[srcPos + i]; @@ -66,14 +72,19 @@ class System { /** * */ - static void arraycopy(const std::vector& src, size_t srcPos, - std::vector& dest, size_t destPos, size_t length) + static void + arraycopy( + const std::vector& src, + size_t srcPos, + std::vector& dest, + size_t destPos, + size_t length) { if ((srcPos + length) >= src.size()) { throw ArrayIndexOutOfBoundsException("pos + offset > src size"); } - if ((srcPos + length) >= src.size()) { + if ((srcPos + length) >= dest.size()) { throw ArrayIndexOutOfBoundsException("pos + offset > dest size"); } @@ -82,8 +93,13 @@ class System { } } - static void arraycopy(const std::vector& src, size_t srcPos, - std::vector& dest, size_t destPos, size_t length) + static void + arraycopy( + const std::vector& src, + size_t srcPos, + std::vector& dest, + size_t destPos, + size_t length) { if ((srcPos + length) > src.size()) { throw ArrayIndexOutOfBoundsException("pos + offset > src size"); @@ -101,26 +117,28 @@ class System { /** * */ - static unsigned long long currentTimeMillis() + static uint64_t + currentTimeMillis() { - return (unsigned long long)(nanoTime() / pow(10, 6)); + return static_cast(nanoTime() / pow(10, 6)); } /** * */ - template - static unsigned int identityHashCode(const std::shared_ptr t) + template + static uint32_t + identityHashCode(const std::shared_ptr t) { if (t == nullptr) { return 0; } - return static_cast(reinterpret_cast(t.get())); + return static_cast(reinterpret_cast(t.get())); } }; -} -} -} -} +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/cpp/Thread.h b/include/keyple/core/util/cpp/Thread.hpp similarity index 50% rename from src/main/cpp/Thread.h rename to include/keyple/core/util/cpp/Thread.hpp index daab363..6e7122b 100644 --- a/src/main/cpp/Thread.h +++ b/include/keyple/core/util/cpp/Thread.hpp @@ -1,19 +1,22 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once #include #include +#include +#include #include namespace keyple { @@ -26,7 +29,7 @@ class Thread { /** * */ - class UncaughtExceptionHandler {}; + class UncaughtExceptionHandler { }; /** * Constructor @@ -36,17 +39,27 @@ class Thread { * * @param name the name of the new thread */ - Thread(const std::string& name) - : mDone(false), mAlive(false), mName(name), mInterrupted(false), mDedicatedThread(false) {} + explicit Thread(const std::string& name) + : mDone(false) + , mAlive(false) + , mName(name) + , mInterrupted(false) + , mDedicatedThread(false) + { + } /** * Constructor * - * Allocates a new Thread object. This constructor has the same effect as Thread (null, null, - * gname), where gname is a newly generated name. Automatically generated names are of the form - * "Thread-"+n, where n is an integer. + * Allocates a new Thread object. This constructor has the same effect as + * Thread (null, null, gname), where gname is a newly generated name. + * Automatically generated names are of the form "Thread-"+n, where n is an + * integer. */ - Thread() : Thread("Thread-x") {} + Thread() + : Thread("Thread-x") + { + } /** * Destructor @@ -56,7 +69,8 @@ class Thread { /** * */ - void setName(const std::string& name) + void + setName(const std::string& name) { mName = name; } @@ -64,15 +78,17 @@ class Thread { /** * Causes this thread to begin execution. * - * The result is that two threads are running concurrently: the current thread (which returns - * from the call to the start method) and the other thread (which executes its run method). + * The result is that two threads are running concurrently: the current + * thread (which returns from the call to the start method) and the other + * thread (which executes its run method). * - * It is never legal to start a thread more than once. In particular, a thread may not be - * restarted once it has completed execution. + * It is never legal to start a thread more than once. In particular, a + * thread may not be restarted once it has completed execution. * * @throw IllegalThreadStateException if the thread was already started. */ - void start() + void + start() { mAlive = true; mDedicatedThread = true; @@ -83,7 +99,8 @@ class Thread { /** * */ - void run() + void + run() { mAlive = true; @@ -94,12 +111,14 @@ class Thread { } /** - * By default Pthreads are joinable. meaning you can wait for them to complete with a call to - * pthread_join(). The Thread class join method checks to see if the thread is running, then - * calls this function to wait for the thread to complete. If the call is successful the thread - * is marked as detached since pthread_join() automatically detatches a thread. + * By default Pthreads are joinable. meaning you can wait for them to + * complete with a call to pthread_join(). The Thread class join method + * checks to see if the thread is running, then calls this function to wait + * for the thread to complete. If the call is successful the thread is + * marked as detached since pthread_join() automatically detatches a thread. */ - int join() + int + join() { int result = -1; @@ -113,29 +132,35 @@ class Thread { /** * */ - bool isAlive() + bool + isAlive() { /* Perform live check if dedicated thread is in use */ if (mDedicatedThread == true) { - mAlive = (mThread.wait_for(std::chrono::milliseconds(0)) != std::future_status::ready); + mAlive + = (mThread.wait_for(std::chrono::milliseconds(0)) + != std::future_status::ready); } return mAlive; } /** - * Causes the currently executing thread to sleep (temporarily cease execution) for the - * specified number of milliseconds, subject to the precision and accuracy of system timers and - * schedulers. The thread does not lose ownership of any monitors. + * Causes the currently executing thread to sleep (temporarily cease + * execution) for the specified number of milliseconds, subject to the + * precision and accuracy of system timers and schedulers. The thread does + * not lose ownership of any monitors. * * @param millis the length of time to sleep in milliseconds * * @throws IllegalArgumentException if the value of millis is negative - * @throws InterruptedException if any thread has interrupted the current thread. The - * interrupted status of the current thread is cleared when this exception is thrown. - * static void sleep(long millis) throw(InterruptedException) + * @throws InterruptedException if any thread has interrupted the current + * thread. The interrupted status of the current thread is cleared when this + * exception is thrown. static void sleep(long millis) + * throw(InterruptedException) */ - static void sleep(long millis) + static void + sleep(uint64_t millis) { std::this_thread::sleep_for(std::chrono::milliseconds(millis)); } @@ -143,29 +168,34 @@ class Thread { /** * Interrupts this thread. * - * Unless the current thread is interrupting itself, which is always permitted, the checkAccess - * method of this thread is invoked, which may cause a SecurityException to be thrown. + * Unless the current thread is interrupting itself, which is always + * permitted, the checkAccess method of this thread is invoked, which may + * cause a SecurityException to be thrown. * - * If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) - * methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or - * sleep(long, int), methods of this class, then its interrupt status will be cleared and it - * will receive an InterruptedException. + * If this thread is blocked in an invocation of the wait(), wait(long), or + * wait(long, int) methods of the Object class, or of the join(), + * join(long), join(long, int), sleep(long), or sleep(long, int), methods of + * this class, then its interrupt status will be cleared and it will receive + * an InterruptedException. * - * If this thread is blocked in an I/O operation upon an interruptible channel then the channel - * will be closed, the thread's interrupt status will be set, and the thread will receive a - * ClosedByInterruptException. + * If this thread is blocked in an I/O operation upon an interruptible channel + * then the channel will be closed, the thread's interrupt status will be + * set, and the thread will receive a ClosedByInterruptException. * - * If this thread is blocked in a Selector then the thread's interrupt status will be set and it - * will return immediately from the selection operation, possibly with a non-zero value, just as - * if the selector's wakeup method were invoked. + * If this thread is blocked in a Selector then the thread's interrupt + * status will be set and it will return immediately from the selection + * operation, possibly with a non-zero value, just as if the selector's + * wakeup method were invoked. * - * If none of the previous conditions hold then this thread's interrupt status will be set. + * If none of the previous conditions hold then this thread's interrupt + * status will be set. * * Interrupting a thread that is not alive need not have any effect. * * @throws SecurityException if the current thread cannot modify this thread */ - void interrupt() + void + interrupt() { mInterrupted = true; } @@ -173,7 +203,8 @@ class Thread { /** * */ - bool isInterrupted() const + bool + isInterrupted() const { return mInterrupted; } @@ -181,7 +212,8 @@ class Thread { /** * */ - std::string getName() + const std::string& + getName() { return mName; } @@ -189,7 +221,8 @@ class Thread { /** * */ - void setUncaughtExceptionHandler(std::shared_ptr eh) + void + setUncaughtExceptionHandler(std::shared_ptr eh) { mUncaughtExceptionHandler = eh; } @@ -232,15 +265,17 @@ class Thread { bool mDedicatedThread; /** - * In the call to pthread_create() the last argument is a void pointer to a data structure which - * will be passed to the runThread() function when it is called. Since the input argument to the - * runThread() is the Thread class this pointer, we can cast it to a Thread pointer then use it - * to call the Thread::run() method. Due to polymorphism, the Thread subclass run() method will - * be called to carry out the thread’s action. + * In the call to pthread_create() the last argument is a void pointer to a + * data structure which will be passed to the runThread() function when it + * is called. Since the input argument to the runThread() is the Thread + * class this pointer, we can cast it to a Thread pointer then use it to + * call the Thread::run() method. Due to polymorphism, the Thread subclass + * run() method will be called to carry out the thread’s action. */ - static void runThread(void* arg) + static void + runThread(void* arg) { - ((Thread*)arg)->execute(); + (static_cast(arg))->execute(); } /** @@ -249,7 +284,7 @@ class Thread { virtual void execute() = 0; }; -} -} -} -} +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/ArrayIndexOutOfBoundsException.hpp b/include/keyple/core/util/cpp/exception/ArrayIndexOutOfBoundsException.hpp new file mode 100644 index 0000000..c3260f4 --- /dev/null +++ b/include/keyple/core/util/cpp/exception/ArrayIndexOutOfBoundsException.hpp @@ -0,0 +1,52 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" +#include "keyple/core/util/cpp/exception/IndexOutOfBoundsException.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class ArrayIndexOutOfBoundsException : public IndexOutOfBoundsException { +public: + /** + * + */ + explicit ArrayIndexOutOfBoundsException(const std::string& message) + : IndexOutOfBoundsException(message) + { + } + + /** + * + */ + ArrayIndexOutOfBoundsException( + const std::string& message, const Exception& cause) + : IndexOutOfBoundsException(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/AssertionError.hpp b/include/keyple/core/util/cpp/exception/AssertionError.hpp new file mode 100644 index 0000000..aaa68ae --- /dev/null +++ b/include/keyple/core/util/cpp/exception/AssertionError.hpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include + +#include "keyple/core/util/cpp/exception/Error.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class AssertionError : public Error { +public: + /** + * + */ + AssertionError() + : Error() + { + } + + /** + * + */ + explicit AssertionError(const std::string& msg) + : Error(msg) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/ClassNotFoundException.hpp b/include/keyple/core/util/cpp/exception/ClassNotFoundException.hpp new file mode 100644 index 0000000..fc059eb --- /dev/null +++ b/include/keyple/core/util/cpp/exception/ClassNotFoundException.hpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class ClassNotFoundException : public Exception { +public: + /** + * + */ + explicit ClassNotFoundException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + ClassNotFoundException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/cpp/exception/Error.h b/include/keyple/core/util/cpp/exception/Error.hpp similarity index 54% rename from src/main/cpp/exception/Error.h rename to include/keyple/core/util/cpp/exception/Error.hpp index 7035421..3f84289 100644 --- a/src/main/cpp/exception/Error.h +++ b/include/keyple/core/util/cpp/exception/Error.hpp @@ -1,14 +1,15 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once @@ -26,12 +27,18 @@ class Error : public std::exception { /** * */ - Error() : mMessage("") {} + Error() + : mMessage("") + { + } /** * */ - Error(const std::string& msg) : mMessage(msg) {} + explicit Error(const std::string& msg) + : mMessage(msg) + { + } private: /** @@ -40,8 +47,8 @@ class Error : public std::exception { const std::string mMessage; }; -} -} -} -} -} +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/Exception.hpp b/include/keyple/core/util/cpp/exception/Exception.hpp new file mode 100644 index 0000000..4abd57a --- /dev/null +++ b/include/keyple/core/util/cpp/exception/Exception.hpp @@ -0,0 +1,145 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class Exception : public std::exception { +public: + /** + * + */ + Exception() = default; + + /** + * + */ + ~Exception() = default; + + /** + * Copy constructor. + */ + Exception(const Exception& o) + : mMessage(o.mMessage) + , mCause(o.mCause) + { + } + + /** + * + */ + explicit Exception(const std::string& message) + : mMessage(message) + { + } + + /** + * + */ + Exception(const std::string& message, const Exception& cause) + : mMessage(message) + , mCause(cause) + { + } + + /** + * Returns the detail message string of this exception. + */ + const std::string& + getMessage() const + { + return mMessage; + } + + /** + * Returns the cause of the exception. + */ + const std::exception& + getCause() const + { + return mCause; + } + + /** + * + */ + const char* + what() const noexcept override + { + return mMessage.c_str(); + } + + /** + * + */ + friend std::ostream& + operator<<(std::ostream& os, const Exception& e) + { + os << "EXCEPTION: {" + << "MESSAGE = " << e.mMessage << ", " + << "CAUSE = " << e.mCause.what() << "}"; + + return os; + } + + /** + * Copy assignment operator. + */ + Exception& + operator=(const Exception& o) + { + if (this != &o) { /* Not a self-assignment */ + this->mMessage = o.mMessage; + this->mCause = o.mCause; + } + + return *this; + } + + /** + * + */ + bool + operator==(const Exception& o) const + { + return mMessage == o.mMessage && mCause.what() == o.mCause.what(); + } + +private: + /** + * + */ + std::string mMessage; + + /** + * + */ + std::exception mCause; +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/FileNotFoundException.hpp b/include/keyple/core/util/cpp/exception/FileNotFoundException.hpp new file mode 100644 index 0000000..be743e4 --- /dev/null +++ b/include/keyple/core/util/cpp/exception/FileNotFoundException.hpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include + +#include "keyple/core/util/cpp/exception/IOException.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class FileNotFoundException : public IOException { +public: + /** + * + */ + explicit FileNotFoundException(const std::string& message) + : IOException(message) + { + } + + /** + * + */ + FileNotFoundException(const std::string& message, const Exception cause) + : IOException(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/IOException.hpp b/include/keyple/core/util/cpp/exception/IOException.hpp new file mode 100644 index 0000000..e4a0795 --- /dev/null +++ b/include/keyple/core/util/cpp/exception/IOException.hpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class IOException : public Exception { +public: + /** + * + */ + explicit IOException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + IOException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/IllegalAccessException.hpp b/include/keyple/core/util/cpp/exception/IllegalAccessException.hpp new file mode 100644 index 0000000..9ca11e3 --- /dev/null +++ b/include/keyple/core/util/cpp/exception/IllegalAccessException.hpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class IllegalAccessException : public Exception { +public: + /** + * + */ + explicit IllegalAccessException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + IllegalAccessException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/IllegalArgumentException.hpp b/include/keyple/core/util/cpp/exception/IllegalArgumentException.hpp new file mode 100644 index 0000000..f33ffbc --- /dev/null +++ b/include/keyple/core/util/cpp/exception/IllegalArgumentException.hpp @@ -0,0 +1,50 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class IllegalArgumentException : public Exception { +public: + /** + * + */ + explicit IllegalArgumentException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + IllegalArgumentException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/IllegalStateException.hpp b/include/keyple/core/util/cpp/exception/IllegalStateException.hpp new file mode 100644 index 0000000..4418e6d --- /dev/null +++ b/include/keyple/core/util/cpp/exception/IllegalStateException.hpp @@ -0,0 +1,50 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class IllegalStateException : public Exception { +public: + /** + * + */ + explicit IllegalStateException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + IllegalStateException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/IndexOutOfBoundsException.hpp b/include/keyple/core/util/cpp/exception/IndexOutOfBoundsException.hpp new file mode 100644 index 0000000..73b6908 --- /dev/null +++ b/include/keyple/core/util/cpp/exception/IndexOutOfBoundsException.hpp @@ -0,0 +1,51 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/cpp/exception/RuntimeException.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class IndexOutOfBoundsException : public RuntimeException { +public: + /** + * + */ + explicit IndexOutOfBoundsException(const std::string& message) + : RuntimeException(message) + { + } + + /** + * + */ + IndexOutOfBoundsException( + const std::string& message, const Exception& cause) + : RuntimeException(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/InstantiationException.hpp b/include/keyple/core/util/cpp/exception/InstantiationException.hpp new file mode 100644 index 0000000..ba14650 --- /dev/null +++ b/include/keyple/core/util/cpp/exception/InstantiationException.hpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class InstantiationException : public Exception { +public: + /** + * + */ + explicit InstantiationException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + InstantiationException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/InterruptedException.hpp b/include/keyple/core/util/cpp/exception/InterruptedException.hpp new file mode 100644 index 0000000..2b0fed7 --- /dev/null +++ b/include/keyple/core/util/cpp/exception/InterruptedException.hpp @@ -0,0 +1,50 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class InterruptedException : public Exception { +public: + /** + * + */ + explicit InterruptedException(const std::string& name) + : Exception(name) + { + } + + /** + * + */ + InterruptedException(const std::string& name, const Exception& cause) + : Exception(name, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/InvocationTargetException.hpp b/include/keyple/core/util/cpp/exception/InvocationTargetException.hpp new file mode 100644 index 0000000..044502f --- /dev/null +++ b/include/keyple/core/util/cpp/exception/InvocationTargetException.hpp @@ -0,0 +1,50 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class InvocationTargetException : public Exception { +public: + /** + * + */ + explicit InvocationTargetException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + InvocationTargetException( + const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/NameNotFoundException.hpp b/include/keyple/core/util/cpp/exception/NameNotFoundException.hpp new file mode 100644 index 0000000..fafd8e4 --- /dev/null +++ b/include/keyple/core/util/cpp/exception/NameNotFoundException.hpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class NameNotFoundException : public Exception { +public: + /** + * + */ + explicit NameNotFoundException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + NameNotFoundException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/NegativeArraySizeException.hpp b/include/keyple/core/util/cpp/exception/NegativeArraySizeException.hpp new file mode 100644 index 0000000..223387a --- /dev/null +++ b/include/keyple/core/util/cpp/exception/NegativeArraySizeException.hpp @@ -0,0 +1,51 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/cpp/exception/RuntimeException.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class NegativeArraySizeException : public RuntimeException { +public: + /** + * + */ + explicit NegativeArraySizeException(const std::string& message) + : RuntimeException(message) + { + } + + /** + * + */ + NegativeArraySizeException( + const std::string& message, const Exception& cause) + : RuntimeException(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/NoSuchElementException.hpp b/include/keyple/core/util/cpp/exception/NoSuchElementException.hpp new file mode 100644 index 0000000..23fce8f --- /dev/null +++ b/include/keyple/core/util/cpp/exception/NoSuchElementException.hpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class NoSuchElementException : public Exception { +public: + /** + * + */ + explicit NoSuchElementException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + NoSuchElementException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/NoSuchMethodException.hpp b/include/keyple/core/util/cpp/exception/NoSuchMethodException.hpp new file mode 100644 index 0000000..d7adec7 --- /dev/null +++ b/include/keyple/core/util/cpp/exception/NoSuchMethodException.hpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class NoSuchMethodException : public Exception { +public: + /** + * + */ + explicit NoSuchMethodException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + NoSuchMethodException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/NumberFormatException.hpp b/include/keyple/core/util/cpp/exception/NumberFormatException.hpp new file mode 100644 index 0000000..064fe9a --- /dev/null +++ b/include/keyple/core/util/cpp/exception/NumberFormatException.hpp @@ -0,0 +1,58 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class NumberFormatException : public Exception { +public: + /** + * + */ + NumberFormatException() + : Exception() + { + } + + /** + * + */ + explicit NumberFormatException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + NumberFormatException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/PatternSyntaxException.hpp b/include/keyple/core/util/cpp/exception/PatternSyntaxException.hpp new file mode 100644 index 0000000..ba5649c --- /dev/null +++ b/include/keyple/core/util/cpp/exception/PatternSyntaxException.hpp @@ -0,0 +1,50 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class PatternSyntaxException : public IllegalArgumentException { +public: + /** + * + */ + explicit PatternSyntaxException(const std::string& message) + : IllegalArgumentException(message) + { + } + + /** + * + */ + PatternSyntaxException(const std::string& message, const Exception& cause) + : IllegalArgumentException(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/RuntimeException.hpp b/include/keyple/core/util/cpp/exception/RuntimeException.hpp new file mode 100644 index 0000000..3bec2ae --- /dev/null +++ b/include/keyple/core/util/cpp/exception/RuntimeException.hpp @@ -0,0 +1,55 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class RuntimeException : public Exception { +public: + /** + * Constructor. + */ + RuntimeException() = default; + + /** + * + */ + explicit RuntimeException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + RuntimeException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/SecurityException.hpp b/include/keyple/core/util/cpp/exception/SecurityException.hpp new file mode 100644 index 0000000..851c562 --- /dev/null +++ b/include/keyple/core/util/cpp/exception/SecurityException.hpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include + +#include "keyple/core/util/cpp/exception/Exception.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class SecurityException : public Exception { +public: + /** + * + */ + explicit SecurityException(const std::string& message) + : Exception(message) + { + } + + /** + * + */ + SecurityException(const std::string& message, const Exception& cause) + : Exception(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/StringIndexOutOfBoundsException.hpp b/include/keyple/core/util/cpp/exception/StringIndexOutOfBoundsException.hpp new file mode 100644 index 0000000..676986a --- /dev/null +++ b/include/keyple/core/util/cpp/exception/StringIndexOutOfBoundsException.hpp @@ -0,0 +1,51 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/cpp/exception/IndexOutOfBoundsException.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class StringIndexOutOfBoundsException : public IndexOutOfBoundsException { +public: + /** + * + */ + explicit StringIndexOutOfBoundsException(const std::string& message) + : IndexOutOfBoundsException(message) + { + } + + /** + * + */ + StringIndexOutOfBoundsException( + const std::string& message, const Exception& cause) + : IndexOutOfBoundsException(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/include/keyple/core/util/cpp/exception/UnsupportedOperationException.hpp b/include/keyple/core/util/cpp/exception/UnsupportedOperationException.hpp new file mode 100644 index 0000000..8d4667f --- /dev/null +++ b/include/keyple/core/util/cpp/exception/UnsupportedOperationException.hpp @@ -0,0 +1,59 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#pragma once + +#include +#include + +#include "keyple/core/util/cpp/exception/RuntimeException.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { +namespace exception { + +class UnsupportedOperationException : public RuntimeException { +public: + /** + * + */ + UnsupportedOperationException() + : RuntimeException() + { + } + + /** + * + */ + explicit UnsupportedOperationException(const std::string& message) + : RuntimeException(message) + { + } + + /** + * + */ + UnsupportedOperationException( + const std::string& message, const Exception& cause) + : RuntimeException(message, cause) + { + } +}; + +} /* namespace exception */ +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/protocol/ContactCardCommonProtocol.h b/include/keyple/core/util/protocol/ContactCardCommonProtocol.hpp similarity index 63% rename from src/main/protocol/ContactCardCommonProtocol.h rename to include/keyple/core/util/protocol/ContactCardCommonProtocol.hpp index 6ad0650..6397549 100644 --- a/src/main/protocol/ContactCardCommonProtocol.h +++ b/include/keyple/core/util/protocol/ContactCardCommonProtocol.hpp @@ -1,21 +1,21 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once #include -/* Keyple Core Util */ -#include "KeypleUtilExport.h" +#include "keyple/core/util/KeypleUtilExport.hpp" namespace keyple { namespace core { @@ -23,7 +23,8 @@ namespace util { namespace protocol { /** - * This enum contains a non-exhaustive list of contacts smartcard communication protocols. + * This enum contains a non-exhaustive list of contacts smartcard communication + * protocols. * * @since 2.0.0 */ @@ -55,10 +56,10 @@ class KEYPLEUTIL_API ContactCardCommonProtocol { /** * */ - ContactCardCommonProtocol(const std::string& name); + explicit ContactCardCommonProtocol(const std::string& name); }; -} -} -} -} +} /* namespace protocol */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/protocol/ContactlessCardCommonProtocol.h b/include/keyple/core/util/protocol/ContactlessCardCommonProtocol.hpp similarity index 66% rename from src/main/protocol/ContactlessCardCommonProtocol.h rename to include/keyple/core/util/protocol/ContactlessCardCommonProtocol.hpp index 60e67cc..c7bd07e 100644 --- a/src/main/protocol/ContactlessCardCommonProtocol.h +++ b/include/keyple/core/util/protocol/ContactlessCardCommonProtocol.hpp @@ -1,21 +1,21 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #pragma once #include -/* Keyple Core Util */ -#include "KeypleUtilExport.h" +#include "keyple/core/util/KeypleUtilExport.hpp" namespace keyple { namespace core { @@ -23,7 +23,8 @@ namespace util { namespace protocol { /** - * This enum contains a non-exhaustive list of contactless smartcard communication protocols. + * This enum contains a non-exhaustive list of contactless smartcard + * communication protocols. * * @since 2.0.0 */ @@ -57,10 +58,10 @@ class KEYPLEUTIL_API ContactlessCardCommonProtocol { /** * */ - ContactlessCardCommonProtocol(const std::string& name); + explicit ContactlessCardCommonProtocol(const std::string& name); }; -} -} -} -} +} /* namespace protocol */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000..5f71ad9 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3a60988..08a2b57 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,16 +1,13 @@ -# ************************************************************************************************* -# Copyright (c) 2021 Calypso Networks Association * -# https://www.calypsonet-asso.org/ * -# * -# See the NOTICE file(s) distributed with this work for additional information regarding * -# copyright ownership. * -# * -# This program and the accompanying materials are made available under the terms of the Eclipse * -# Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * -# * -# SPDX-License-Identifier: EPL-2.0 * -# *************************************************************************************************/ +# ***************************************************************************** +# Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * +# * +# This program and the accompanying materials are made available under the * +# terms of the MIT License which is available at * +# https://opensource.org/licenses/MIT. * +# * +# SPDX-License-Identifier: MIT * +# *****************************************************************************/ # Add projects ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/main/) -#ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/test/) +ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/test/) diff --git a/src/main/ByteArrayUtil.cpp b/src/main/ByteArrayUtil.cpp deleted file mode 100755 index 702defb..0000000 --- a/src/main/ByteArrayUtil.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2023 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#include "ByteArrayUtil.h" - -/* Keyple Core Util */ -#include "Character.h" -#include "HexUtil.h" -#include "IllegalArgumentException.h" -#include "KeypleAssert.h" -#include "NegativeArraySizeException.h" -#include "Pattern.h" -#include "StringBuilder.h" -#include "System.h" - -namespace keyple { -namespace core { -namespace util { - -using namespace keyple::core::util::cpp; -using namespace keyple::core::util::cpp::exception; - -const std::vector ByteArrayUtil::extractBytes(const std::vector& src, - const int bitOffset, - const int nbBytes) -{ - if (bitOffset < 0) { - throw ArrayIndexOutOfBoundsException("negative index"); - } - - if (nbBytes < 0) { - throw NegativeArraySizeException("negative array size"); - } - - const int byteOffset = bitOffset / 8; - int lBitOffset = bitOffset % 8; - - if (byteOffset >= static_cast((src.size() - (lBitOffset ? 1 : 0)))) { - throw ArrayIndexOutOfBoundsException("pos + offset > src size"); - } - - std::vector dest(nbBytes); - - if (lBitOffset == 0) { - System::arraycopy(src, byteOffset, dest, 0, nbBytes); - } else { - const int rightShift = 8 - bitOffset; - for (int i = 0, j = byteOffset; j < byteOffset + nbBytes; i++, j++) { - dest[i] = ((src[j] << lBitOffset) | ((src[j + 1] & 0xFF) >> rightShift)); - } - } - - return dest; -} - -const std::vector ByteArrayUtil::extractBytes(const uint64_t src, const int nbBytes) -{ - if (nbBytes < 0) { - throw NegativeArraySizeException("negative array size"); - } - - std::vector data(nbBytes); - int shift = 0; - int i = nbBytes - 1; - - while (i >= 0) { - data[i] = ((src >> shift) & 0xFF); - shift += 8; - i--; - } - - return data; -} - -uint16_t ByteArrayUtil::extractShort(const std::vector& src, const int offset) -{ - if (offset < 0 || offset > static_cast(src.size() - 2)) { - throw ArrayIndexOutOfBoundsException("offset not in range [0...(src.size() - 2)"); - } - - return ((src[offset] & 0xFF) << 8) | (src[offset + 1] & 0xFF); -} - -uint32_t ByteArrayUtil::extractInt(const std::vector& src, - const int offset, - const int nbBytes, - const bool isSigned) -{ - if (offset < 0) { - - throw ArrayIndexOutOfBoundsException("negative offset"); - } - - if ((offset + nbBytes) > static_cast(src.size())) { - - throw ArrayIndexOutOfBoundsException("offset + nbBytes > src size"); - } - - /* C++ - doesn't make sense to have nbBytes > int size */ - if (nbBytes > 4) { - - throw IllegalArgumentException("nbBytes can't be bigger than 4"); - } - - uint32_t val = 0; - uint32_t complement = 0xFFFFFFFF; - int lOffset = offset; - int lNbBytes = nbBytes; - bool negative = false; - - /* Check MSB byte negativeness */ - negative = src[lOffset] > 0x7F; - - /* Get value */ - while (lNbBytes > 0) { - - val |= ((src[lOffset++] & 0xFF) << (8 * (--lNbBytes))); - complement &= ~(0xFF << 8 * lNbBytes); - } - - /* If signed, add complement */ - if (isSigned && negative) { - - val |= complement; - } - - return (uint32_t)val; -} - -uint64_t ByteArrayUtil::extractLong(const std::vector& src, - const int offset, - const int nbBytes, - const bool isSigned) -{ - int lOffset = offset; - int lNbBytes = nbBytes; - - - if (lOffset < 0 || lOffset > static_cast(src.size() - lNbBytes)) { - throw ArrayIndexOutOfBoundsException("offset not in range [0...(src.size() - nbBytes)"); - } - - uint64_t val = 0L; - uint64_t complement = 0xFFFFFFFFFFFFFFFF; - bool negative = false; - - /* Get value */ - while (lNbBytes > 0) { - /* Check MSB byte negativeness */ - negative = negative ? true : ((src[lOffset] & 0xFF) > 0x7F ? true : false); - val |= (((uint64_t)(src[lOffset++] & 0xFF)) << (8 * (--lNbBytes))); - complement &= ~(((uint64_t)0xFF) << 8 * lNbBytes); - } - - /* If signed, add complement */ - if (isSigned && negative) { - val |= complement; - } - - return (uint64_t)val; -} - -void ByteArrayUtil::copyBytes(const uint64_t src, - std::vector& dest, - const int offset, - const int nbBytes) -{ - if (offset < 0 || offset > static_cast(dest.size() - nbBytes)) { - throw ArrayIndexOutOfBoundsException("offset not in range [0...(dest.size() - nbBytes)"); - } - - System::arraycopy(extractBytes(src, nbBytes), 0, dest, offset, nbBytes); -} - -bool ByteArrayUtil::isValidHexString(const std::string& hex) -{ - return HexUtil::isValid(hex); -} - -const std::string ByteArrayUtil::normalizeHexString(const std::string& hex) -{ - if (hex.length() % 2 != 0) { - return "0" + hex; - } - - return hex; -} - -std::vector ByteArrayUtil::fromHex(const std::string& hex) -{ - Assert::getInstance().notEmpty(hex, "hex").isEqual(hex.length() % 2, 0, "hex size"); - - return HexUtil::toByteArray(hex); -} - -const std::string ByteArrayUtil::toHex(const std::vector& src) -{ - if (src.empty()) { - return ""; - } - - return HexUtil::toHex(src); -} - -int ByteArrayUtil::twoBytesToInt(const std::vector& bytes, const int offset) -{ - return extractInt(bytes, offset, 2, false); -} - -int ByteArrayUtil::twoBytesSignedToInt(const std::vector& bytes, const int offset) -{ - return extractInt(bytes, offset, 2, true); -} - -int ByteArrayUtil::threeBytesToInt(const std::vector& bytes, const int offset) -{ - return extractInt(bytes, offset, 3, false); -} - -int ByteArrayUtil::threeBytesSignedToInt(const std::vector& bytes, const int offset) -{ - return extractInt(bytes, offset, 3, true); -} - -int ByteArrayUtil::fourBytesToInt(const std::vector& bytes, const int offset) -{ - return extractInt(bytes, offset, 4, true); -} - -} -} -} diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt index 75fc142..dcb9f26 100755 --- a/src/main/CMakeLists.txt +++ b/src/main/CMakeLists.txt @@ -1,14 +1,13 @@ -# ************************************************************************************************* -# Copyright (c) 2021 Calypso Networks Association http://calypsonet.org/ * -# * -# See the NOTICE file(s) distributed with this work for additional information regarding * -# copyright ownership. * -# * -# This program and the accompanying materials are made available under the terms of the Eclipse * -# Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * -# * -# SPDX-License-Identifier: EPL-2.0 * -# *************************************************************************************************/ +# ***************************************************************************** +# Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * +# * +# This program and the accompanying materials are made available under the * +# terms of the MIT License which is available at * +# https://opensource.org/licenses/MIT. * +# * +# SPDX-License-Identifier: MIT * +# *****************************************************************************/ + SET(LIBRARY_NAME keypleutilcpplib) @@ -19,26 +18,33 @@ ADD_LIBRARY( ${LIBRARY_TYPE} - ${CMAKE_CURRENT_SOURCE_DIR}/ApduUtil.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/BerTlvUtil.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/ByteArrayUtil.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/HexUtil.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/KeypleAssert.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/cpp/Logger.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/cpp/LoggerFactory.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/cpp/Matcher.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/cpp/Pattern.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/protocol/ContactCardCommonProtocol.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/protocol/ContactlessCardCommonProtocol.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keyple/core/util/ApduUtil.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keyple/core/util/BerTlvUtil.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keyple/core/util/ByteArrayUtil.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keyple/core/util/HexUtil.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keyple/core/util/KeypleAssert.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keyple/core/util/cpp/Logger.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keyple/core/util/cpp/LoggerFactory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keyple/core/util/cpp/Matcher.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keyple/core/util/cpp/Pattern.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keyple/core/util/protocol/ContactCardCommonProtocol.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/keyple/core/util/protocol/ContactlessCardCommonProtocol.cpp ) TARGET_INCLUDE_DIRECTORIES( + ${LIBRARY_NAME} + PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/protocol - ${CMAKE_CURRENT_SOURCE_DIR}/cpp - ${CMAKE_CURRENT_SOURCE_DIR}/cpp/exception + + $ ) -ADD_LIBRARY(Keyple::Util ALIAS ${LIBRARY_NAME}) +ADD_LIBRARY( + + Keyple::Util + + ALIAS + + ${LIBRARY_NAME} +) diff --git a/src/main/HexUtil.cpp b/src/main/HexUtil.cpp deleted file mode 100644 index 19bf894..0000000 --- a/src/main/HexUtil.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#include "HexUtil.h" - -#include - -/* Keyple Core Util */ -#include "StringIndexOutOfBoundsException.h" - -namespace keyple { -namespace core { -namespace util { - -using namespace keyple::core::util::cpp::exception; - -const std::vector HexUtil::mByteToHex = { - "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", - "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", - "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", - "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", - "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", - "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", - "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", - "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", - "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", - "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", - "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", - "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", - "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF", - "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", - "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", - "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" -}; - -const std::vector HexUtil::mHexToNibble = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -}; - -HexUtil::HexUtil() {} - -bool HexUtil::isValid(const std::string& hex) -{ - if (hex.length() == 0 || hex.length() % 2 != 0) { - return false; - } - - for (int i = 0; i < static_cast(hex.size()); i++) { - if (mHexToNibble[hex.at(i)] == 0xFF) { - return false; - } - } - - return true; -} - -const std::vector HexUtil::toByteArray(const std::string& hex) -{ - std::vector tab(hex.size() / 2); - - if (hex.length() % 2) { - throw StringIndexOutOfBoundsException("string has odd length"); - } - - for (int i = 0; i < static_cast(hex.length()); i += 2) { - tab[i / 2] = ((mHexToNibble[hex.at(i)] << 4) + - (mHexToNibble[hex.at(i + 1)] & 0xFF)); - } - - return tab; -} - -uint8_t HexUtil::toByte(const std::string& hex) -{ - uint8_t val = 0; - - for (int i = 0; i < static_cast(hex.length()); i++) { - val <<= 4; - val |= (mHexToNibble[hex.at(i)] & 0xFF); - } - - return val; -} - -uint16_t HexUtil::toShort(const std::string& hex) -{ - uint16_t val = 0; - - for (int i = 0; i < static_cast(hex.length()); i++) { - val <<= 4; - val |= (mHexToNibble[hex.at(i)] & 0xFF); - } - - return val; -} - -uint32_t HexUtil::toInt(const std::string& hex) -{ - uint32_t val = 0; - - for (int i = 0; i < static_cast(hex.length()); i++) { - val <<= 4; - val |= (mHexToNibble[hex.at(i)] & 0xFF); - } - - return val; -} - -uint64_t HexUtil::toLong(const std::string& hex) -{ - uint64_t val = 0; - - for (int i = 0; i < static_cast(hex.length()); i++) { - val <<= 4; - val |= (mHexToNibble[hex.at(i)] & 0xFF); - } - - return val; -} - -const std::string HexUtil::toHex(const std::vector& tab) -{ - std::stringstream ss; - - for (const auto& b : tab) { - ss << (mByteToHex[b & 0xFF]); - } - - return ss.str(); -} - -const std::string HexUtil::toHex(const uint8_t val) -{ - return mByteToHex[val & 0xFF]; -} - -const std::string HexUtil::toHex(const uint16_t val) -{ - if ((val & 0xFF00) == 0) { - return mByteToHex[val & 0xFF]; - } - - return mByteToHex[val >> 8 & 0xFF] + mByteToHex[val & 0xFF]; -} - -const std::string HexUtil::toHex(const uint32_t val) -{ - if ((val & 0xFFFFFF00) == 0) { - return mByteToHex[val & 0xFF]; - } else if ((val & 0xFFFF0000) == 0) { - return mByteToHex[val >> 8 & 0xFF] + - mByteToHex[val & 0xFF]; - } else if ((val & 0xFF000000) == 0) { - return mByteToHex[val >> 16 & 0xFF] + - mByteToHex[val >> 8 & 0xFF] + - mByteToHex[val & 0xFF]; - } - - return mByteToHex[val >> 24 & 0xFF] + - mByteToHex[val >> 16 & 0xFF] + - mByteToHex[val >> 8 & 0xFF] + - mByteToHex[val & 0xFF]; -} - -const std::string HexUtil::toHex(const uint64_t val) -{ - if ((val & 0xFFFFFFFFFFFFFF00L) == 0) { - return mByteToHex[(int) (val & 0xFF)]; - } else if ((val & 0xFFFFFFFFFFFF0000L) == 0) { - return mByteToHex[(int) (val >> 8 & 0xFF)] + - mByteToHex[(int) (val & 0xFF)]; - } else if ((val & 0xFFFFFFFFFF000000L) == 0) { - return mByteToHex[(int) (val >> 16 & 0xFF)] + - mByteToHex[(int) (val >> 8 & 0xFF)] + - mByteToHex[(int) (val & 0xFF)]; - } else if ((val & 0xFFFFFFFF00000000L) == 0) { - return mByteToHex[(int) (val >> 24 & 0xFF)] + - mByteToHex[(int) (val >> 16 & 0xFF)] + - mByteToHex[(int) (val >> 8 & 0xFF)] + - mByteToHex[(int) (val & 0xFF)]; - } else if ((val & 0xFFFFFF0000000000L) == 0) { - return mByteToHex[(int) (val >> 32 & 0xFF)] + - mByteToHex[(int) (val >> 24 & 0xFF)] + - mByteToHex[(int) (val >> 16 & 0xFF)] + - mByteToHex[(int) (val >> 8 & 0xFF)] + - mByteToHex[(int) (val & 0xFF)]; - } else if ((val & 0xFFFF000000000000L) == 0) { - return mByteToHex[(int) (val >> 40 & 0xFF)] + - mByteToHex[(int) (val >> 32 & 0xFF)] + - mByteToHex[(int) (val >> 24 & 0xFF)] + - mByteToHex[(int) (val >> 16 & 0xFF)] + - mByteToHex[(int) (val >> 8 & 0xFF)] + - mByteToHex[(int) (val & 0xFF)]; - } else if ((val & 0xFF00000000000000L) == 0) { - return mByteToHex[(int) (val >> 48 & 0xFF)] + - mByteToHex[(int) (val >> 40 & 0xFF)] + - mByteToHex[(int) (val >> 32 & 0xFF)] + - mByteToHex[(int) (val >> 24 & 0xFF)] + - mByteToHex[(int) (val >> 16 & 0xFF)] + - mByteToHex[(int) (val >> 8 & 0xFF)] + - mByteToHex[(int) (val & 0xFF)]; - } - - return mByteToHex[(int) (val >> 56 & 0xFF)] + - mByteToHex[(int) (val >> 48 & 0xFF)] + - mByteToHex[(int) (val >> 40 & 0xFF)] + - mByteToHex[(int) (val >> 32 & 0xFF)] + - mByteToHex[(int) (val >> 24 & 0xFF)] + - mByteToHex[(int) (val >> 16 & 0xFF)] + - mByteToHex[(int) (val >> 8 & 0xFF)] + - mByteToHex[(int) (val & 0xFF)]; -} - -} -} -} diff --git a/src/main/KeypleAssert.cpp b/src/main/KeypleAssert.cpp deleted file mode 100644 index 0dbe213..0000000 --- a/src/main/KeypleAssert.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#include "KeypleAssert.h" - -/* Keyple Core Util */ -#include "HexUtil.h" - -namespace keyple { -namespace core { -namespace util { - -const std::string Assert::ARGUMENT = "Argument ["; -const std::string Assert::CONDITION = "Condition ["; -const std::string Assert::HAS_A_VALUE = "] has a value ["; -const std::string Assert::LESS_THAN = "] less than ["; -const std::string Assert::GREATER_THAN = "] greater than ["; -const std::string Assert::IS_NULL = "] is null."; -const std::string Assert::IS_EMPTY = "] is empty."; -const std::string Assert::IS_FALSE = "] is false."; -const std::string Assert::IS_NOT_HEX = "] is not a hex string."; -const std::string Assert::NOT_EQUAL_TO = "] not equal to ["; -const std::string Assert::CLOSING_BRACKET = "]."; - -Assert::Assert() {} - -Assert& Assert::getInstance() -{ - static Assert INSTANCE; - - return INSTANCE; -} - -Assert& Assert::notEmpty(const std::string& obj, const std::string& name) -{ - - if (obj == "") { - throw IllegalArgumentException(ARGUMENT + name + IS_EMPTY); - } - - return *this; -} - -Assert& Assert::notEmpty(const std::vector& obj, const std::string& name) -{ - if (obj.size() == 0) { - throw IllegalArgumentException(ARGUMENT + name + IS_EMPTY); - } - - return *this; -} - -Assert& Assert::isTrue(const bool condition, const std::string& name) -{ - if (!condition) { - throw IllegalArgumentException(CONDITION + name + IS_FALSE); - } - - return *this; -} - -Assert& Assert::greaterOrEqual(const size_t number, const size_t minValue, const std::string& name) -{ - if (number < minValue) { - throw IllegalArgumentException(ARGUMENT + - name + - HAS_A_VALUE + - std::to_string(number) + - LESS_THAN + - std::to_string(minValue) + - CLOSING_BRACKET); - } - - return *this; -} - -Assert& Assert::isEqual(const size_t number, const size_t value, const std::string& name) -{ - if (number != value) { - throw IllegalArgumentException(ARGUMENT + - name + - HAS_A_VALUE + - std::to_string(number) + - NOT_EQUAL_TO + - std::to_string(value) + - CLOSING_BRACKET); - } - - return *this; -} - -Assert& Assert::isInRange(const size_t number, - const size_t minValue, - const size_t maxValue, - const std::string& name) -{ - if (number < minValue) { - throw IllegalArgumentException(ARGUMENT + - name + - HAS_A_VALUE + - std::to_string(number) + - LESS_THAN + - std::to_string(minValue) + - CLOSING_BRACKET); - } else if (number > maxValue) { - throw IllegalArgumentException(ARGUMENT + - name + - HAS_A_VALUE + - std::to_string(number) + - GREATER_THAN + - std::to_string(maxValue) + - CLOSING_BRACKET); - } - - return *this; -} - -Assert& Assert::isHexString(const std::string& hex, const std::string& name) -{ - if (!HexUtil::isValid(hex)) { - throw IllegalArgumentException(ARGUMENT + name + IS_NOT_HEX); - } - - return *this; -} - -} -} -} diff --git a/src/main/cpp/Any.h b/src/main/cpp/Any.h deleted file mode 100644 index db67549..0000000 --- a/src/main/cpp/Any.h +++ /dev/null @@ -1,511 +0,0 @@ -// -// Implementation of N4562 std::experimental::any (merged into C++17) for C++11 compilers. -// -// See also: -// + http://en.cppreference.com/w/cpp/any -// + http://en.cppreference.com/w/cpp/experimental/any -// + http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4562.html#any -// + https://cplusplus.github.io/LWG/lwg-active.html#2509 -// -// -// Copyright (c) 2016 Denilson das Mercês Amorim -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -#ifndef LINB_ANY_HPP -#define LINB_ANY_HPP -#pragma once -#include -#include -#include -#include - - -#if defined(PARTICLE) -#if !defined(__cpp_exceptions) && !defined(ANY_IMPL_NO_EXCEPTIONS) && !defined(ANY_IMPL_EXCEPTIONS) -# define ANY_IMPL_NO_EXCEPTIONS -# endif -#else -// you can opt-out of exceptions by definining ANY_IMPL_NO_EXCEPTIONS, -// but you must ensure not to cast badly when passing an `any' object to any_cast(any) -#endif - -#if defined(PARTICLE) -#if !defined(__cpp_rtti) && !defined(ANY_IMPL_NO_RTTI) && !defined(ANY_IMPL_RTTI) -# define ANY_IMPL_NO_RTTI -# endif -#else -// you can opt-out of RTTI by defining ANY_IMPL_NO_RTTI, -// in order to disable functions working with the typeid of a type -#endif - - -namespace keyple { -namespace core { -namespace util { -namespace cpp { - -class bad_any_cast : public std::bad_cast -{ -public: - const char* what() const noexcept override - { - return "bad any cast"; - } -}; - -class any final -{ -public: - /// Constructs an object of type any with an empty state. - any() : - vtable(nullptr) - { - } - - /// Constructs an object of type any with an equivalent state as other. - any(const any& rhs) : - vtable(rhs.vtable) - { - if(!rhs.empty()) - { - rhs.vtable->copy(rhs.storage, this->storage); - } - } - - /// Constructs an object of type any with a state equivalent to the original state of other. - /// rhs is left in a valid but otherwise unspecified state. - any(any&& rhs) noexcept : - vtable(rhs.vtable) - { - if(!rhs.empty()) - { - rhs.vtable->move(rhs.storage, this->storage); - rhs.vtable = nullptr; - } - } - - /// Same effect as this->clear(). - ~any() - { - this->clear(); - } - - /// Constructs an object of type any that contains an object of type T direct-initialized with std::forward(value). - /// - /// T shall satisfy the CopyConstructible requirements, otherwise the program is ill-formed. - /// This is because an `any` may be copy constructed into another `any` at any time, so a copy should always be allowed. - template::type, any>::value>::type> - any(ValueType&& value) - { - static_assert(std::is_copy_constructible::type>::value, - "T shall satisfy the CopyConstructible requirements."); - this->construct(std::forward(value)); - } - - /// Has the same effect as any(rhs).swap(*this). No effects if an exception is thrown. - any& operator=(const any& rhs) - { - any(rhs).swap(*this); - return *this; - } - - /// Has the same effect as any(std::move(rhs)).swap(*this). - /// - /// The state of *this is equivalent to the original state of rhs and rhs is left in a valid - /// but otherwise unspecified state. - any& operator=(any&& rhs) noexcept - { - any(std::move(rhs)).swap(*this); - return *this; - } - - /// Has the same effect as any(std::forward(value)).swap(*this). No effect if a exception is thrown. - /// - /// T shall satisfy the CopyConstructible requirements, otherwise the program is ill-formed. - /// This is because an `any` may be copy constructed into another `any` at any time, so a copy should always be allowed. - template::type, any>::value>::type> - any& operator=(ValueType&& value) - { - static_assert(std::is_copy_constructible::type>::value, - "T shall satisfy the CopyConstructible requirements."); - any(std::forward(value)).swap(*this); - return *this; - } - - /// If not empty, destroys the contained object. - void clear() noexcept - { - if(!empty()) - { - this->vtable->destroy(storage); - this->vtable = nullptr; - } - } - - /// Returns true if *this has no contained object, otherwise false. - bool empty() const noexcept - { - return this->vtable == nullptr; - } - -#ifndef ANY_IMPL_NO_RTTI - /// If *this has a contained object of type T, typeid(T); otherwise typeid(void). - const std::type_info& type() const noexcept - { - return empty()? typeid(void) : this->vtable->type(); - } -#endif - - /// Exchange the states of *this and rhs. - void swap(any& rhs) noexcept - { - if(this->vtable != rhs.vtable) - { - any tmp(std::move(rhs)); - - // move from *this to rhs. - rhs.vtable = this->vtable; - if(this->vtable != nullptr) - { - this->vtable->move(this->storage, rhs.storage); - //this->vtable = nullptr; -- unneeded, see below - } - - // move from tmp (previously rhs) to *this. - this->vtable = tmp.vtable; - if(tmp.vtable != nullptr) - { - tmp.vtable->move(tmp.storage, this->storage); - tmp.vtable = nullptr; - } - } - else // same types - { - if(this->vtable != nullptr) - this->vtable->swap(this->storage, rhs.storage); - } - } - -private: // Storage and Virtual Method Table - - union storage_union - { - using stack_storage_t = typename std::aligned_storage<2 * sizeof(void*), std::alignment_of::value>::type; - - void* dynamic; - stack_storage_t stack; // 2 words for e.g. shared_ptr - }; - - /// Base VTable specification. - struct vtable_type - { - // Note: The caller is responssible for doing .vtable = nullptr after destructful operations - // such as destroy() and/or move(). - -#ifndef ANY_IMPL_NO_RTTI - /// The type of the object this vtable is for. - const std::type_info& (*type)() noexcept; -#endif - - /// Destroys the object in the union. - /// The state of the union after this call is unspecified, caller must ensure not to use src anymore. - void(*destroy)(storage_union&) noexcept; - - /// Copies the **inner** content of the src union into the yet unitialized dest union. - /// As such, both inner objects will have the same state, but on separate memory locations. - void(*copy)(const storage_union& src, storage_union& dest); - - /// Moves the storage from src to the yet unitialized dest union. - /// The state of src after this call is unspecified, caller must ensure not to use src anymore. - void(*move)(storage_union& src, storage_union& dest) noexcept; - - /// Exchanges the storage between lhs and rhs. - void(*swap)(storage_union& lhs, storage_union& rhs) noexcept; - }; - - /// VTable for dynamically allocated storage. - template - struct vtable_dynamic - { -#ifndef ANY_IMPL_NO_RTTI - static const std::type_info& type() noexcept - { - return typeid(T); - } -#endif - - static void destroy(storage_union& storage) noexcept - { - //assert(reinterpret_cast(storage.dynamic)); - delete reinterpret_cast(storage.dynamic); - } - - static void copy(const storage_union& src, storage_union& dest) - { - dest.dynamic = new T(*reinterpret_cast(src.dynamic)); - } - - static void move(storage_union& src, storage_union& dest) noexcept - { - dest.dynamic = src.dynamic; - src.dynamic = nullptr; - } - - static void swap(storage_union& lhs, storage_union& rhs) noexcept - { - // just exchage the storage pointers. - std::swap(lhs.dynamic, rhs.dynamic); - } - }; - - /// VTable for stack allocated storage. - template - struct vtable_stack - { -#ifndef ANY_IMPL_NO_RTTI - static const std::type_info& type() noexcept - { - return typeid(T); - } -#endif - - static void destroy(storage_union& storage) noexcept - { - reinterpret_cast(&storage.stack)->~T(); - } - - static void copy(const storage_union& src, storage_union& dest) - { - new (&dest.stack) T(reinterpret_cast(src.stack)); - } - - static void move(storage_union& src, storage_union& dest) noexcept - { - // one of the conditions for using vtable_stack is a nothrow move constructor, - // so this move constructor will never throw a exception. - new (&dest.stack) T(std::move(reinterpret_cast(src.stack))); - destroy(src); - } - - static void swap(storage_union& lhs, storage_union& rhs) noexcept - { - storage_union tmp_storage; - move(rhs, tmp_storage); - move(lhs, rhs); - move(tmp_storage, lhs); - } - }; - - /// Whether the type T must be dynamically allocated or can be stored on the stack. - template - struct requires_allocation : - std::integral_constant::value // N4562 §6.3/3 [any.class] - && sizeof(T) <= sizeof(storage_union::stack) - && std::alignment_of::value <= std::alignment_of::value)> - {}; - - /// Returns the pointer to the vtable of the type T. - template - static vtable_type* vtable_for_type() - { - using VTableType = typename std::conditional::value, vtable_dynamic, vtable_stack>::type; - static vtable_type table = { -#ifndef ANY_IMPL_NO_RTTI - VTableType::type, -#endif - VTableType::destroy, - VTableType::copy, VTableType::move, - VTableType::swap, - }; - return &table; - } - -protected: - template - friend const T* any_cast(const any* operand) noexcept; - template - friend T* any_cast(any* operand) noexcept; - -#ifndef ANY_IMPL_NO_RTTI - /// Same effect as is_same(this->type(), t); - bool is_typed(const std::type_info& t) const - { - return is_same(this->type(), t); - } -#endif - -#ifndef ANY_IMPL_NO_RTTI - /// Checks if two type infos are the same. - /// - /// If ANY_IMPL_FAST_TYPE_INFO_COMPARE is defined, checks only the address of the - /// type infos, otherwise does an actual comparision. Checking addresses is - /// only a valid approach when there's no interaction with outside sources - /// (other shared libraries and such). - static bool is_same(const std::type_info& a, const std::type_info& b) - { -#ifdef ANY_IMPL_FAST_TYPE_INFO_COMPARE - return &a == &b; -#else - return a == b; -#endif - } -#endif - - /// Casts (with no type_info checks) the storage pointer as const T*. - template - const T* cast() const noexcept - { - return requires_allocation::type>::value? - reinterpret_cast(storage.dynamic) : - reinterpret_cast(&storage.stack); - } - - /// Casts (with no type_info checks) the storage pointer as T*. - template - T* cast() noexcept - { - return requires_allocation::type>::value? - reinterpret_cast(storage.dynamic) : - reinterpret_cast(&storage.stack); - } - -private: - storage_union storage = { 0 }; // on offset(0) so no padding for align - vtable_type* vtable; - - template - typename std::enable_if::value>::type - do_construct(ValueType&& value) - { - storage.dynamic = new T(std::forward(value)); - } - - template - typename std::enable_if::value>::type - do_construct(ValueType&& value) - { - new (&storage.stack) T(std::forward(value)); - } - - /// Chooses between stack and dynamic allocation for the type decay_t, - /// assigns the correct vtable, and constructs the object on our storage. - template - void construct(ValueType&& value) - { - using T = typename std::decay::type; - - this->vtable = vtable_for_type(); - - do_construct(std::forward(value)); - } -}; - - - -namespace detail -{ - template - inline ValueType any_cast_move_if_true(typename std::remove_reference::type* p, std::true_type) - { - return std::move(*p); - } - - template - inline ValueType any_cast_move_if_true(typename std::remove_reference::type* p, std::false_type) - { - return *p; - } -} - -/// Performs *any_cast>>(&operand), or throws bad_any_cast on failure. -template -inline ValueType any_cast(const any& operand) -{ - auto p = any_cast::type>::type>(&operand); -#ifndef ANY_IMPL_NO_EXCEPTIONS - if(p == nullptr) throw bad_any_cast(); -#endif - return *p; -} - -/// Performs *any_cast>(&operand), or throws bad_any_cast on failure. -template -inline ValueType any_cast(any& operand) -{ - auto p = any_cast::type>(&operand); -#ifndef ANY_IMPL_NO_EXCEPTIONS - if(p == nullptr) throw bad_any_cast(); -#endif - return *p; -} - -/// -/// If ValueType is MoveConstructible and isn't a lvalue reference, performs -/// std::move(*any_cast>(&operand)), otherwise -/// *any_cast>(&operand). Throws bad_any_cast on failure. -/// -template -inline ValueType any_cast(any&& operand) -{ - using can_move = std::integral_constant::value - && !std::is_lvalue_reference::value>; - - auto p = any_cast::type>(&operand); -#ifndef ANY_IMPL_NO_EXCEPTIONS - if(p == nullptr) throw bad_any_cast(); -#endif - return detail::any_cast_move_if_true(p, can_move()); -} - -/// If operand != nullptr && operand->type() == typeid(ValueType), a pointer to the object -/// contained by operand, otherwise nullptr. -template -inline const ValueType* any_cast(const any* operand) noexcept -{ - using T = typename std::decay::type; - -#ifndef ANY_IMPL_NO_RTTI - if (operand && operand->is_typed(typeid(T))) -#else - if (operand && operand->vtable == any::vtable_for_type()) -#endif - return operand->cast(); - else - return nullptr; -} - -/// If operand != nullptr && operand->type() == typeid(ValueType), a pointer to the object -/// contained by operand, otherwise nullptr. -template -inline ValueType* any_cast(any* operand) noexcept -{ - using T = typename std::decay::type; - -#ifndef ANY_IMPL_NO_RTTI - if (operand && operand->is_typed(typeid(T))) -#else - if (operand && operand->vtable == any::vtable_for_type()) -#endif - return operand->cast(); - else - return nullptr; -} - -} -} -} -} - -namespace std -{ - inline void swap(keyple::core::util::cpp::any& lhs, keyple::core::util::cpp::any& rhs) noexcept - { - lhs.swap(rhs); - } -} - -#endif diff --git a/src/main/cpp/KeypleStd.h b/src/main/cpp/KeypleStd.h deleted file mode 100644 index 3fe0b72..0000000 --- a/src/main/cpp/KeypleStd.h +++ /dev/null @@ -1,161 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace std { - -// when using a compiler that does not support C++17, define our own implementation of reinterpret_pointer_cast -#if !defined(_WIN32) && !(defined(__APPLE__) && defined(__clang__)) && __cplusplus < 201703L -template -inline std::shared_ptr reinterpret_pointer_cast(std::shared_ptr const & ptr) noexcept -{ - return std::shared_ptr(ptr, reinterpret_cast(ptr.get())); -} -#endif - -inline std::ostream& operator<<(std::ostream& os, const uint8_t v) -{ - os << static_cast(v) - << "(0x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) - << static_cast(v) << ")"; - - return os; -} - -inline std::ostream& operator<<(std::ostream& os, const std::vector& v) -{ - for (int i = 0; i < static_cast(v.size()); i++) - os << std::uppercase << std::hex << std::setfill('0') << std::setw(2) - << static_cast(v[i]); - - return os; -} - -inline std::ostream& operator<<(std::ostream& os, const std::vector& v) -{ - for (int i = 0; i < static_cast(v.size()); i++) { - if (i != 0) { - os << ", "; - } - - os << std::hex << std::setfill('0') << std::setw(8) - << static_cast(v[i]); - } - - return os; -} - -inline std::ostream& operator<<(std::ostream& os, const std::vector& v) -{ - os << "{"; - for (auto it = v.begin(); it != v.end(); ++it) - { - if (it != v.begin()) - os << ", "; - os << *it; - } - os << "}"; - - return os; -} - -inline std::ostream& operator<<(std::ostream& os, const std::set& s) -{ - os << "{"; - for (auto it = s.begin(); it != s.end(); ++it) - { - if (it != s.begin()) - os << ", "; - os << *it; - } - os << "}"; - - return os; -} - -template -inline -std::ostream& operator<<(std::ostream& os, const std::map& s) -{ - os << "MAP: {"; - for (auto it = s.begin(); it != s.end(); ++it) - { - if (it != s.begin()) - os << ", "; - os << "{" << it->first << ", " << it->second << "}"; - } - os << "}"; - - return os; -} - -template -inline -std::ostream& operator<<(std::ostream& os, const std::map& s) -{ - os << "MAP: {"; - for (auto it = s.begin(); it != s.end(); ++it) - { - if (it != s.begin()) - os << ", "; - os << "{" << it->first << ", " << it->second << "}"; - } - os << "}"; - - return os; -} - -template -inline void split(const std::string &s, const std::regex& re, out result) -{ - std::sregex_token_iterator d(s.begin(), s.end(), re, -1); - std::sregex_token_iterator end; - - while (d != end) { - *result++ = *d++; - } -} - -/* Trim from left */ -inline std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v") -{ - s.erase(0, s.find_first_not_of(t)); - - return s; -} - -/* Trim from right */ -inline std::string& rtrim(std::string& s, const char* t = " \t\n\r\f\v") -{ - s.erase(s.find_last_not_of(t) + 1); - - return s; -} - -/* Trim from left & right */ -inline std::string& trim(std::string& s, const char* t = " \t\n\r\f\v") -{ - return ltrim(rtrim(s, t), t); -} - -} diff --git a/src/main/cpp/Logger.cpp b/src/main/cpp/Logger.cpp deleted file mode 100644 index e088685..0000000 --- a/src/main/cpp/Logger.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#include - -#include "Logger.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { - -Logger::Level Logger::mLevel = Logger::Level::logDebug; - -Logger::Logger(const std::string& className, std::mutex* mtx) -: className(demangle(className.c_str())), mtx(mtx) {} - -std::string Logger::getClassName() -{ - return className; -} - -void Logger::setLoggerLevel(Logger::Level level) -{ - mLevel = level; -} - -const std::string Logger::getCurrentTimestamp() -{ - using std::chrono::system_clock; - auto currentTime = std::chrono::system_clock::now(); - char buffer1[21]; - char buffer2[26]; - - auto transformed = currentTime.time_since_epoch().count() / 1000000; - auto millis = transformed % 1000; - - std::time_t tt; - tt = system_clock::to_time_t(currentTime); - auto timeinfo = localtime(&tt); - - strftime(buffer1, sizeof(buffer1), "%F %H:%M:%S", timeinfo); - snprintf(buffer2, sizeof(buffer2), "%s:%03d", buffer1, (int)millis); - - return std::string(buffer2); -} - -} -} -} -} diff --git a/src/main/cpp/LoggerFactory.cpp b/src/main/cpp/LoggerFactory.cpp deleted file mode 100644 index 22eedf1..0000000 --- a/src/main/cpp/LoggerFactory.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#include "LoggerFactory.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { - -std::mutex LoggerFactory::mtx; - -std::unique_ptr LoggerFactory::getLogger(const std::type_info& type) -{ - return std::unique_ptr(new Logger(type.name(), &mtx)); -} - -} -} -} -} diff --git a/src/main/cpp/MapUtils.h b/src/main/cpp/MapUtils.h deleted file mode 100644 index 71b6c6e..0000000 --- a/src/main/cpp/MapUtils.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include -#include - -namespace keyple { -namespace core { -namespace util { -namespace cpp { - -using namespace keyple::core::util::cpp::exception; - -class MapUtils { -public: - template - static const std::vector getKeySet(const std::map& m) - { - std::vector v; - - for (const auto& e : m) { - v.push_back(e.first); - } - - return v; - } - - template - static const std::vector getValueSet(const std::map& m) - { - std::vector v; - - for (const auto& e : m) { - v.push_back(e.second); - } - - return v; - } -}; - -} -} -} -} diff --git a/src/main/cpp/Matcher.h b/src/main/cpp/Matcher.h deleted file mode 100644 index 6cd4f88..0000000 --- a/src/main/cpp/Matcher.h +++ /dev/null @@ -1,236 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include -#include -#include - -#include "KeypleUtilExport.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { - -class Pattern; - -class KEYPLEUTIL_API Matcher { -public: - /** - * All matchers have the state used by Pattern during a match. - */ - Matcher(const Pattern* parent, const std::string& text); - - /** - * Initiates a search for an anchored match to a Pattern within the given bounds. The groups are - * filled with default values and the match of the root of the state machine is called. The - * state machine will hold the state of the match as it proceeds in this matcher. - */ - bool match(const int from, const int anchor) const; - - /** - * Attempts to match the entire region against the pattern. - * - *

If the match succeeds then more information can be obtained via the start, - * end, and group methods.

- * - * @return true if, and only if, the entire region sequence matches this matcher's - * pattern - */ - bool matches(); - - /** - * Replaces every subsequence of the input sequence that matches the pattern with the given - * replacement string. - * - *

This method first resets this matcher. It then scans the input sequence looking for - * matches of the pattern. Characters that are not part of any match are appended directly to - * the result string; each match is replaced in the result by the replacement string. The - * replacement string may contain references to captured subsequences as in the - * appendReplacement() method. - * - *

Note that backslashes (\\) and dollar signs ($) in the replacement - * string may cause the results to be different than if it were being treated as a literal - * replacement string. Dollar signs may be treated as references to captured subsequences as - * described above, and backslashes are used to escape literal characters in the replacement - * string. - * - *

Given the regular expression a*b, the input "aabfooaabfooabfoob", and - * the replacement string "-", an invocation of this method on a matcher for that - * expression would yield the string "-foo-foo-foo-". - * - *

Invoking this method changes this matcher's state. If the matcher is to be used in - * further matching operations then it should first be reset.

- * - * @param replacement The replacement string - * @return The string constructed by replacing each matching subsequence by the replacement - * string, substituting captured subsequences as needed - */ - std::string replaceAll(const std::string& replacement) const; - - /** - * Attempts to find the next subsequence of the input sequence that matches the pattern. - * - * This method starts at the beginning of this matcher's region, o, if a previous invocation of - * the method was successful and the matcher has not since been reset, at the first character - * not matched by the previous match. - * - * If the match succeeds then more information can be obtained viw the start, end, group - * methods. - * - * @return true if, and only if, a subsequence of the input sequences matches this matcher's - * patern. - */ - bool find(); - - /** - * Resets this matcher and then attempts to find the next subsequence of the input sequence that - * matches the pattern, starting at the specified index. - * - * If the match succeeds then more information can be obtained viw the start, end, group - * methods, and subsequent invocations of the find() method will start at the first character - * not matched by this match. - * - * @return true if, and only if, a subsequence of the input sequences matches this matcher's - * patern. - * @throw IndexOutOfBoundException if start is less than zero of if start is greated than the - * length of the input sequence. - */ - bool find(const int start); - - /** - * Returns the text that matched a given group of the regular expression. Explicit capturing - * groups in the pattern are numbered left to right in order of their opening parenthesis, - * starting at 1. The special group 0 represents the entire match (as if the entier pattern is - * surrounded by an implicit capturing group). - * - * For example, "a((b)c)" matching "abc" would give the following groups: - * 0 "abc" - * 1 "bc" - * 2 "b" - * - * An optional capturing group that failed to match as part of an overall sucessful match (for - * example "a(b)?c" matching "ac") returns null. A capturing group that matched the empty string - * (for example, "a(b?)c" matching "ac") returns the empty string. - * - * @throw IllegalStateException if no successful match has been made - */ - const std::string group(const int group) const; - - /** - * Returns the text that matched the whole regular expression. - * - * @return the text - * - * @throw IllegalStateException if no successful match has been made - */ - const std::string group() const; - - /** - * Initiates a search to find a Pattern within the given bounds. The groups are filled with - * defaults values and the match of the root of the state machine is called. The state machine - * will hold the state of the match as it proceeds in this matcher. - * - * Matcher.from is not set here, because it is the 'hard' boundary of the start of the search - * which anchors will set to. The from param is the 'soft' boundary of the start of the search, - * meaning that the regex tries to match at that index but won't match there. Subsequent calls - * to the search methods start at a new 'soft' boundary which is the end of the previous match. - */ - bool search(const int from); - - /** - * Returns the end index of the text. - * - * @return the index after the last charaecter in the text - */ - int getTextLength() const; - - /** - * Resets this matcher. - * - *

Resetting a matcher discards all of its explicit states information and sets its append - * position to zero. The matcher's region is set to the default region, which is its entire - * character sequence. The anchoring and transparency of this matcher's region boundaries are - * unaffected. - */ - Matcher* reset(); - -private: - /** - * The Pattern object that created this Matcher. - */ - const Pattern* mParentPattern; - - /** - * The original string being matched. - */ - const std::string mText; - - /** - * The range within the sequence that is to be matched. Anchors will match at these "hard" - * boundaries. Changing the region changes these values. - */ - int mFrom; - int mTo; - - /** - * Matcher state used by the last node. NOANCHOR is used when a match does not have to consume - * all of the input. ENDANCHOR is the mode used for matching all the input. - */ - int ENDANCHOR = 1; - - /** - * The range of string that last matched the pattern. If the last match failed then first is -1; - * last initially holds 0 then it holds the index of the end of the last match (which is where - * the next search starts). - */ - int mFirst = -1, mLast = 0; - - /** - * The end index of what matched in the last match operation. - */ - int mOldLast = -1; - - /** - * Substring on which the regex_search is applied. It used to be a temp variable whithin the - * Matcher::search() function but for some reasons, on Windows, the 'groups' std::smatch doesn't - * keep its data after leaving the Matcher::search() function (e.g. in other words, it's very - * probable that std::match only provides references to specific locations in an existing - * string). - */ - std::string mSubs; - - /** - * The storage used by groups. They may contain invalid values if a group was skipped during the - * matching. - */ - std::smatch mGroups; - - /** - * The index of the last position appended in the substitution. - */ - int mLastAppendPosition = 0; - - /** - * Storage used by nodes to tell what repetition they are on in a pattern, and where groups - * begin. The nodes themselves are stateless, so they rely on this field to hold state during a - * match. - */ - std::vector mLocals; -}; - -} -} -} -} diff --git a/src/main/cpp/Pattern.cpp b/src/main/cpp/Pattern.cpp deleted file mode 100644 index 00107a3..0000000 --- a/src/main/cpp/Pattern.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#include "Pattern.h" - -/* Keyple Core Utils */ -#include "PatternSyntaxException.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { - -using namespace keyple::core::util::cpp::exception; - -Pattern::Pattern(const std::string& pattern, const int flags) : mPattern(pattern), mFlags(flags) {} - -std::unique_ptr Pattern::compile(const std::string& regularExpression, const int flags) - const -{ - /* Compiler hack */ - (void)mFlags; - - try { - return std::unique_ptr(new Pattern(regularExpression, flags)); - } catch (const std::exception& e) { - throw PatternSyntaxException(e.what()); - } -} - -std::unique_ptr Pattern::compile(const std::string& pattern) -{ - try { - return std::unique_ptr(new Pattern(pattern, 0)); - } catch (const std::exception& e) { - throw PatternSyntaxException(e.what()); - } -} - -std::unique_ptr Pattern::matcher(const std::string& input) const -{ - return std::unique_ptr(new Matcher(this, input)); -} - -} -} -} -} diff --git a/src/main/cpp/Pattern.h b/src/main/cpp/Pattern.h deleted file mode 100644 index 9b80f88..0000000 --- a/src/main/cpp/Pattern.h +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include - -#include "KeypleUtilExport.h" -#include "Matcher.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { - -class KEYPLEUTIL_API Pattern { -public: - /** - * - */ - const std::regex mPattern; - - /** - * Constructor - */ - Pattern(const std::string& pattern, const int flags); - - /** - * Returns a compiled form of the given regular expression, as modified by the given flags. - * - * @throws PatternSyntexException - */ - std::unique_ptr compile(const std::string& regularExpression, const int flags) const; - - /** - * Equivalent to Pattern.compile(pattern, 0) - */ - static std::unique_ptr compile(const std::string& pattern); - - /* - * Returns a Matcher for this pattern applied to the given input. The Matcher can be used to - * match the Pattern against the whole input, find occurences of the Pattern in the input, or - * replace parts of the input. - */ - std::unique_ptr matcher(const std::string& input) const; - -private: - - /** - * - */ - const int mFlags; -}; - -} -} -} -} diff --git a/src/main/cpp/StringUtils.h b/src/main/cpp/StringUtils.h deleted file mode 100644 index ead786d..0000000 --- a/src/main/cpp/StringUtils.h +++ /dev/null @@ -1,81 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2023 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include -#include -#include - -namespace keyple { -namespace core { -namespace util { -namespace cpp { - -class StringUtils { -public: - static inline const std::string format(const char* format, ...) - { - char buf[1024]; - va_list args; - - va_start(args, format); - vsnprintf(buf, sizeof(buf), format, args); - va_end(args); - - return buf; - } - - static inline bool contains(const std::string& s1, const std::string& s2) - { - return s1.find(s2) != std::string::npos; - } - - static inline bool matches(const std::string& s, const std::string& regex) - { - std::regex r(regex); - - return std::regex_match(s, r); - } - - static inline const std::vector split(const std::string& string, - const std::string& delimiter) - { - std::vector tokens; - std::string s = string; - - size_t pos = 0; - - while ((pos = s.find(delimiter)) != std::string::npos) { - tokens.push_back(s.substr(0, pos)); - s.erase(0, pos + delimiter.length()); - } - - return tokens; - } - - static inline const std::string tolower(const std::string& string) - { - std::string copy = string; - std::transform(copy.begin(), - copy.end(), - copy.begin(), - [](unsigned char c){ return static_cast(std::tolower(c)); }); - - return copy; - } -}; - -} -} -} -} diff --git a/src/main/cpp/exception/ArrayIndexOutOfBoundsException.h b/src/main/cpp/exception/ArrayIndexOutOfBoundsException.h deleted file mode 100644 index 55fde76..0000000 --- a/src/main/cpp/exception/ArrayIndexOutOfBoundsException.h +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" -#include "IndexOutOfBoundsException.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class ArrayIndexOutOfBoundsException : public IndexOutOfBoundsException { -public: - /** - * - */ - ArrayIndexOutOfBoundsException(const std::string& message) - : IndexOutOfBoundsException(message) {} - - /** - * - */ - ArrayIndexOutOfBoundsException(const std::string& message, - const std::shared_ptr cause) - : IndexOutOfBoundsException(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/AssertionError.h b/src/main/cpp/exception/AssertionError.h deleted file mode 100644 index b9bcae2..0000000 --- a/src/main/cpp/exception/AssertionError.h +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Error.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class AssertionError : public Error { -public: - /** - * - */ - AssertionError() : Error() {} - - /** - * - */ - AssertionError(const std::string& msg) : Error(msg) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/ClassNotFoundException.h b/src/main/cpp/exception/ClassNotFoundException.h deleted file mode 100644 index ebbf690..0000000 --- a/src/main/cpp/exception/ClassNotFoundException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class ClassNotFoundException : public Exception { -public: - /** - * - */ - ClassNotFoundException(const std::string& message) : Exception(message) {} - - /** - * - */ - ClassNotFoundException(const std::string& message, const std::exception cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/Exception.h b/src/main/cpp/exception/Exception.h deleted file mode 100644 index 4590ce0..0000000 --- a/src/main/cpp/exception/Exception.h +++ /dev/null @@ -1,115 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include -#include -#include -#include - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class Exception : public std::exception { -public: - /** - * - */ - Exception() {} - - /** - * - */ - Exception(const Exception& o) : mMessage(o.mMessage), mCause(o.mCause) {} - - /** - * - */ - Exception(const std::string& message) : mMessage(message), mCause(nullptr) {} - - /** - * - */ - Exception(const std::string& message, const std::shared_ptr cause) - : mMessage(message), mCause(cause) {} - - /** - * Returns the detail message string of this exception. - */ - const std::string& getMessage() const - { - return mMessage; - } - - /** - * Returns the cause of the exception. - */ - const std::shared_ptr getCause() const - { - return mCause; - } - - /** - * - */ - const char * what() const noexcept override - { - return mMessage.c_str(); - } - - /** - * - */ - friend std::ostream& operator<<(std::ostream& os, const Exception& e) - { - os << "EXCEPTION: {" - << "MESSAGE = " << e.mMessage; - - if (e.mCause != nullptr) { - os << ", CAUSE = " << e.mCause->what(); - } - - os << "}"; - - return os; - } - - /** - * - */ - bool operator==(const Exception& o) const - { - return mMessage == o.mMessage && - mCause== o.mCause; - } - -private: - /** - * - */ - const std::string mMessage; - - /** - * - */ - const std::shared_ptr mCause; -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/FileNotFoundException.h b/src/main/cpp/exception/FileNotFoundException.h deleted file mode 100644 index 311473d..0000000 --- a/src/main/cpp/exception/FileNotFoundException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "IOException.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class FileNotFoundException : public IOException { -public: - /** - * - */ - FileNotFoundException(const std::string& message) : IOException(message) {} - - /** - * - */ - FileNotFoundException(const std::string& message, const std::exception cause) - : IOException(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/IOException.h b/src/main/cpp/exception/IOException.h deleted file mode 100644 index f72ea8d..0000000 --- a/src/main/cpp/exception/IOException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class IOException : public Exception { -public: - /** - * - */ - IOException(const std::string& message) : Exception(message) {} - - /** - * - */ - IOException(const std::string& message, const std::exception cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/IllegalAccessException.h b/src/main/cpp/exception/IllegalAccessException.h deleted file mode 100644 index 650d1e1..0000000 --- a/src/main/cpp/exception/IllegalAccessException.h +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class IllegalAccessException : public Exception { -public: - /** - * - */ - IllegalAccessException(const std::string& message) : Exception(message) {} - - /** - * - */ - IllegalAccessException( - const std::string& message, const std::exception cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/IllegalArgumentException.h b/src/main/cpp/exception/IllegalArgumentException.h deleted file mode 100644 index 2b4d434..0000000 --- a/src/main/cpp/exception/IllegalArgumentException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2022 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class IllegalArgumentException : public Exception { -public: - /** - * - */ - IllegalArgumentException(const std::string& message) : Exception(message) {} - - /** - * - */ - IllegalArgumentException(const std::string& message, const std::shared_ptr cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/IllegalStateException.h b/src/main/cpp/exception/IllegalStateException.h deleted file mode 100644 index 5aab081..0000000 --- a/src/main/cpp/exception/IllegalStateException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class IllegalStateException : public Exception { -public: - /** - * - */ - IllegalStateException(const std::string& message) : Exception(message) {} - - /** - * - */ - IllegalStateException(const std::string& message, const std::shared_ptr cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/IndexOutOfBoundsException.h b/src/main/cpp/exception/IndexOutOfBoundsException.h deleted file mode 100644 index 913cd55..0000000 --- a/src/main/cpp/exception/IndexOutOfBoundsException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "RuntimeException.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class IndexOutOfBoundsException : public RuntimeException { -public: - /** - * - */ - IndexOutOfBoundsException(const std::string& message) : RuntimeException(message) {} - - /** - * - */ - IndexOutOfBoundsException(const std::string& message, const std::shared_ptr cause) - : RuntimeException(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/InstantiationException.h b/src/main/cpp/exception/InstantiationException.h deleted file mode 100644 index ffff715..0000000 --- a/src/main/cpp/exception/InstantiationException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class InstantiationException : public Exception { -public: - /** - * - */ - InstantiationException(const std::string& message) : Exception(message) {} - - /** - * - */ - InstantiationException(const std::string& message, const std::exception cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/InterruptedException.h b/src/main/cpp/exception/InterruptedException.h deleted file mode 100644 index e71d056..0000000 --- a/src/main/cpp/exception/InterruptedException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class InterruptedException : public Exception { -public: - /** - * - */ - InterruptedException(const std::string& name) : Exception(name) {} - - /** - * - */ - InterruptedException(const std::string& name, const std::shared_ptr cause) - : Exception(name, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/InvocationTargetException.h b/src/main/cpp/exception/InvocationTargetException.h deleted file mode 100644 index bf2d906..0000000 --- a/src/main/cpp/exception/InvocationTargetException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class InvocationTargetException : public Exception { -public: - /** - * - */ - InvocationTargetException(const std::string& message) : Exception(message) {} - - /** - * - */ - InvocationTargetException(const std::string& message, const std::exception cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/NameNotFoundException.h b/src/main/cpp/exception/NameNotFoundException.h deleted file mode 100644 index 77a689c..0000000 --- a/src/main/cpp/exception/NameNotFoundException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class NameNotFoundException : public Exception { -public: - /** - * - */ - NameNotFoundException(const std::string& message) : Exception(message) {} - - /** - * - */ - NameNotFoundException(const std::string& message, const std::exception cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/NegativeArraySizeException.h b/src/main/cpp/exception/NegativeArraySizeException.h deleted file mode 100644 index 1c6aa8d..0000000 --- a/src/main/cpp/exception/NegativeArraySizeException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "RuntimeException.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class NegativeArraySizeException : public RuntimeException { -public: - /** - * - */ - NegativeArraySizeException(const std::string& message) : RuntimeException(message) {} - - /** - * - */ - NegativeArraySizeException(const std::string& message, const std::shared_ptr cause) - : RuntimeException(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/NoSuchElementException.h b/src/main/cpp/exception/NoSuchElementException.h deleted file mode 100644 index 0b68e46..0000000 --- a/src/main/cpp/exception/NoSuchElementException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class NoSuchElementException : public Exception { -public: - /** - * - */ - NoSuchElementException(const std::string& message) : Exception(message) {} - - /** - * - */ - NoSuchElementException(const std::string& message, const std::exception cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/NoSuchMethodException.h b/src/main/cpp/exception/NoSuchMethodException.h deleted file mode 100644 index bbb1ac7..0000000 --- a/src/main/cpp/exception/NoSuchMethodException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class NoSuchMethodException : public Exception { -public: - /** - * - */ - NoSuchMethodException(const std::string& message) : Exception(message) {} - - /** - * - */ - NoSuchMethodException(const std::string& message, const std::exception cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/NumberFormatException.h b/src/main/cpp/exception/NumberFormatException.h deleted file mode 100644 index 1e6bceb..0000000 --- a/src/main/cpp/exception/NumberFormatException.h +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class NumberFormatException : public Exception { -public: - /** - * - */ - NumberFormatException() : Exception() {} - - /** - * - */ - NumberFormatException(const std::string& message) : Exception(message) {} - - /** - * - */ - NumberFormatException(const std::string& message, const std::shared_ptr cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/PatternSyntaxException.h b/src/main/cpp/exception/PatternSyntaxException.h deleted file mode 100644 index 2469c11..0000000 --- a/src/main/cpp/exception/PatternSyntaxException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "IllegalArgumentException.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class PatternSyntaxException : public IllegalArgumentException { -public: - /** - * - */ - PatternSyntaxException(const std::string& message) : IllegalArgumentException(message) {} - - /** - * - */ - PatternSyntaxException(const std::string& message, const std::shared_ptr cause) - : IllegalArgumentException(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/RuntimeException.h b/src/main/cpp/exception/RuntimeException.h deleted file mode 100644 index 2264e78..0000000 --- a/src/main/cpp/exception/RuntimeException.h +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class RuntimeException : public Exception { -public: - /** - * - */ - RuntimeException() : Exception() {} - - /** - * - */ - RuntimeException(const std::string& message) : Exception(message) {} - - /** - * - */ - RuntimeException(const std::string& message, const std::shared_ptr cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/SecurityException.h b/src/main/cpp/exception/SecurityException.h deleted file mode 100644 index ff5b14d..0000000 --- a/src/main/cpp/exception/SecurityException.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "Exception.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class SecurityException : public Exception { -public: - /** - * - */ - SecurityException(const std::string& message) : Exception(message) {} - - /** - * - */ - SecurityException(const std::string& message, const std::exception cause) - : Exception(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/StringIndexOutOfBoundsException.h b/src/main/cpp/exception/StringIndexOutOfBoundsException.h deleted file mode 100644 index fab1c68..0000000 --- a/src/main/cpp/exception/StringIndexOutOfBoundsException.h +++ /dev/null @@ -1,43 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "IndexOutOfBoundsException.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class StringIndexOutOfBoundsException : public IndexOutOfBoundsException { -public: - /** - * - */ - StringIndexOutOfBoundsException(const std::string& message) - : IndexOutOfBoundsException(message) {} - - /** - * - */ - StringIndexOutOfBoundsException(const std::string& message, - const std::shared_ptr cause) - : IndexOutOfBoundsException(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/cpp/exception/UnsupportedOperationException.h b/src/main/cpp/exception/UnsupportedOperationException.h deleted file mode 100644 index df8128c..0000000 --- a/src/main/cpp/exception/UnsupportedOperationException.h +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#pragma once - -#include "RuntimeException.h" - -namespace keyple { -namespace core { -namespace util { -namespace cpp { -namespace exception { - -class UnsupportedOperationException : public RuntimeException { -public: - /** - * - */ - UnsupportedOperationException() : RuntimeException() {} - - /** - * - */ - UnsupportedOperationException(const std::string& message) : RuntimeException(message) {} - - /** - * - */ - UnsupportedOperationException(const std::string& message, - const std::shared_ptr cause) - : RuntimeException(message, cause) {} -}; - -} -} -} -} -} diff --git a/src/main/ApduUtil.cpp b/src/main/keyple/core/util/ApduUtil.cpp old mode 100755 new mode 100644 similarity index 50% rename from src/main/ApduUtil.cpp rename to src/main/keyple/core/util/ApduUtil.cpp index 136cd7f..f06985d --- a/src/main/ApduUtil.cpp +++ b/src/main/keyple/core/util/ApduUtil.cpp @@ -1,34 +1,40 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#include "ApduUtil.h" - -/* Util */ -#include "System.h" +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include "keyple/core/util/ApduUtil.hpp" + +#include + +#include "keyple/core/util/cpp/System.hpp" namespace keyple { namespace core { namespace util { -using namespace keyple::core::util::cpp; +using keyple::core::util::cpp::System; -ApduUtil::ApduUtil() {} +ApduUtil::ApduUtil() +{ +} -const std::vector ApduUtil::build(const uint8_t cla, - const uint8_t ins, - const uint8_t p1, - const uint8_t p2, - const std::vector& dataIn, - const uint8_t le) +const std::vector +ApduUtil::build( + const uint8_t cla, + const uint8_t ins, + const uint8_t p1, + const uint8_t p2, + const std::vector& dataIn, + const uint8_t le) { std::vector apduCommand; @@ -45,7 +51,8 @@ const std::vector ApduUtil::build(const uint8_t cla, if (dataIn.size() != 0) { /* Append Lc and ingoing data */ apduCommand[4] = static_cast(dataIn.size()); - System::arraycopy(dataIn, 0, apduCommand, 5, static_cast(dataIn.size())); + System::arraycopy( + dataIn, 0, apduCommand, 5, static_cast(dataIn.size())); apduCommand[apduCommand.size() - 1] = le; } else { /* Case2: outgoing data only */ @@ -55,11 +62,13 @@ const std::vector ApduUtil::build(const uint8_t cla, return apduCommand; } -const std::vector ApduUtil::build(const uint8_t cla, - const uint8_t ins, - const uint8_t p1, - const uint8_t p2, - const std::vector& dataIn) +const std::vector +ApduUtil::build( + const uint8_t cla, + const uint8_t ins, + const uint8_t p1, + const uint8_t p2, + const std::vector& dataIn) { std::vector apduCommand; @@ -76,7 +85,8 @@ const std::vector ApduUtil::build(const uint8_t cla, if (dataIn.size() != 0) { /* append Lc and ingoing data */ apduCommand[4] = static_cast(dataIn.size()); - System::arraycopy(dataIn, 0, apduCommand, 5, static_cast(dataIn.size())); + System::arraycopy( + dataIn, 0, apduCommand, 5, static_cast(dataIn.size())); /* Case3: ingoing data only, no Le */ } else { /* Case1: no ingoing, no outgoing data, P3/Le = 0 */ @@ -85,11 +95,13 @@ const std::vector ApduUtil::build(const uint8_t cla, return apduCommand; } -const std::vector ApduUtil::build(const uint8_t cla, - const uint8_t ins, - const uint8_t p1, - const uint8_t p2, - const uint8_t le) +const std::vector +ApduUtil::build( + const uint8_t cla, + const uint8_t ins, + const uint8_t p1, + const uint8_t p2, + const uint8_t le) { std::vector apduCommand; @@ -109,10 +121,9 @@ const std::vector ApduUtil::build(const uint8_t cla, return apduCommand; } -const std::vector ApduUtil::build(const uint8_t cla, - const uint8_t ins, - const uint8_t p1, - const uint8_t p2) +const std::vector +ApduUtil::build( + const uint8_t cla, const uint8_t ins, const uint8_t p1, const uint8_t p2) { std::vector apduCommand; @@ -132,49 +143,54 @@ const std::vector ApduUtil::build(const uint8_t cla, return apduCommand; } -std::vector ApduUtil::allocateBuffer(const std::vector& data, const uint8_t le) +std::vector +ApduUtil::allocateBuffer(const std::vector& data, const uint8_t le) { (void)le; - int length = 4; // Header + int length = 4; // Header - length += static_cast(data.size() + 1); // Lc + data - length += 1; // Le + length += static_cast(data.size() + 1); // Lc + data + length += 1; // Le return std::vector(length); } -std::vector ApduUtil::allocateBuffer(const std::vector& data) +std::vector +ApduUtil::allocateBuffer(const std::vector& data) { - int length = 4; // Header + int length = 4; // Header - length += static_cast(data.size() + 1); // Lc + data + length += static_cast(data.size() + 1); // Lc + data return std::vector(length); } -std::vector ApduUtil::allocateBuffer(const uint8_t le) +std::vector +ApduUtil::allocateBuffer(const uint8_t le) { (void)le; - int length = 4; // Header + int length = 4; // Header - length += 1; // Le + length += 1; // Le return std::vector(length); } -std::vector ApduUtil::allocateBuffer() +std::vector +ApduUtil::allocateBuffer() { - int length = 4; // Header + int length = 4; // Header /* Case 1: 5-byte apdu, le=0 */ - length += 1; // Le + length += 1; // Le return std::vector(length); } -bool ApduUtil::isCase4(const std::vector& apduCommand) +bool +ApduUtil::isCase4(const std::vector& apduCommand) { if (apduCommand.size() > 4) { return apduCommand[4] == apduCommand.size() - 6; @@ -183,6 +199,6 @@ bool ApduUtil::isCase4(const std::vector& apduCommand) return false; } -} -} -} +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/BerTlvUtil.cpp b/src/main/keyple/core/util/BerTlvUtil.cpp similarity index 57% rename from src/main/BerTlvUtil.cpp rename to src/main/keyple/core/util/BerTlvUtil.cpp index 454d52f..12c0dbd 100644 --- a/src/main/BerTlvUtil.cpp +++ b/src/main/keyple/core/util/BerTlvUtil.cpp @@ -1,32 +1,39 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#include "BerTlvUtil.h" - -/* Keyple Core Util */ -#include "Arrays.h" -#include "IllegalArgumentException.h" -#include "IndexOutOfBoundsException.h" +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include "keyple/core/util/BerTlvUtil.hpp" + +#include +#include + +#include "keyple/core/util/cpp/Arrays.hpp" +#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp" +#include "keyple/core/util/cpp/exception/IndexOutOfBoundsException.hpp" namespace keyple { namespace core { namespace util { -using namespace keyple::core::util::cpp; -using namespace keyple::core::util::cpp::exception; +using keyple::core::util::cpp::Arrays; +using keyple::core::util::cpp::exception::IllegalArgumentException; +using keyple::core::util::cpp::exception::IndexOutOfBoundsException; -BerTlvUtil::BerTlvUtil() {} +BerTlvUtil::BerTlvUtil() +{ +} -const std::map> BerTlvUtil::parseSimple( +const std::map> +BerTlvUtil::parseSimple( const std::vector& tlvStructure, const bool primitiveOnly) { try { @@ -37,7 +44,8 @@ const std::map> BerTlvUtil::parseSimple( } } -const std::map>> BerTlvUtil::parse( +const std::map>> +BerTlvUtil::parse( const std::vector& tlvStructure, const bool primitiveOnly) { try { @@ -48,7 +56,8 @@ const std::map>> BerTlvUtil::parse( } } -bool BerTlvUtil::isConstructed(const int tagId) +bool +BerTlvUtil::isConstructed(const int tagId) { if (tagId < 0 || tagId > 0xFFFFFF) { throw IllegalArgumentException("Tag Id out of range."); @@ -65,24 +74,25 @@ bool BerTlvUtil::isConstructed(const int tagId) return (tagId & 0x200000) != 0; } -const std::map> BerTlvUtil::parseBufferSimple( +const std::map> +BerTlvUtil::parseBufferSimple( const std::vector& tlvStructure, const bool primitiveOnly) { - std::map> tlvs; int offset = 0; do { const int tagSize = getTagSize(tlvStructure, offset); - const std::vector tagBytes = - Arrays::copyOfRange(tlvStructure, offset, offset + tagSize); + const std::vector tagBytes + = Arrays::copyOfRange(tlvStructure, offset, offset + tagSize); const int tag = getTag(tlvStructure, offset, tagSize); const int lengthSize = getLengthSize(tlvStructure, offset + tagSize); - const int valueSize = getLength(tlvStructure, offset + tagSize, lengthSize); - const std::vector value = - Arrays::copyOfRange(tlvStructure, - offset + tagSize + lengthSize, - offset + tagSize + lengthSize + valueSize); + const int valueSize + = getLength(tlvStructure, offset + tagSize, lengthSize); + const std::vector value = Arrays::copyOfRange( + tlvStructure, + offset + tagSize + lengthSize, + offset + tagSize + lengthSize + valueSize); offset += tagSize + lengthSize + valueSize; @@ -92,8 +102,8 @@ const std::map> BerTlvUtil::parseBufferSim tlvs.insert({tag, value}); } - const std::map> parse = - parseSimple(value, primitiveOnly); + const std::map> parse + = parseSimple(value, primitiveOnly); tlvs.insert(parse.begin(), parse.end()); } else { /* Tag is primitive */ @@ -104,7 +114,8 @@ const std::map> BerTlvUtil::parseBufferSim return tlvs; } -const std::map>> BerTlvUtil::parseBuffer( +const std::map>> +BerTlvUtil::parseBuffer( const std::vector& tlvStructure, const bool primitiveOnly) { std::map>> tlvs; @@ -112,58 +123,64 @@ const std::map>> BerTlvUtil::parseBu do { const int tagSize = getTagSize(tlvStructure, offset); - const std::vector tagBytes = - Arrays::copyOfRange(tlvStructure, offset, offset + tagSize); + const std::vector tagBytes + = Arrays::copyOfRange(tlvStructure, offset, offset + tagSize); const int tag = getTag(tlvStructure, offset, tagSize); const int lengthSize = getLengthSize(tlvStructure, offset + tagSize); - const int valueSize = getLength(tlvStructure, offset + tagSize, lengthSize); - const std::vector value = - Arrays::copyOfRange(tlvStructure, - offset + tagSize + lengthSize, - offset + tagSize + lengthSize + valueSize); + const int valueSize + = getLength(tlvStructure, offset + tagSize, lengthSize); + const std::vector value = Arrays::copyOfRange( + tlvStructure, + offset + tagSize + lengthSize, + offset + tagSize + lengthSize + valueSize); offset += tagSize + lengthSize + valueSize; if ((tagBytes[0] & 0x20) != 0) { /* Tag is constructed */ if (!primitiveOnly) { - std::vector>& values = getOrInitTagValues(tlvs, tag); + std::vector>& values + = getOrInitTagValues(tlvs, tag); values.push_back(value); } - std::map>> tlvs2 = - parse(value, primitiveOnly); + std::map>> tlvs2 + = parse(value, primitiveOnly); - for (const auto & entry : tlvs2) { - std::vector>& values = getOrInitTagValues(tlvs, entry.first); + for (const auto& entry : tlvs2) { + std::vector>& values + = getOrInitTagValues(tlvs, entry.first); Arrays::addAll(values, entry.second); } } else { /* Tag is primitive */ - std::vector>& values = getOrInitTagValues(tlvs, tag); + std::vector>& values + = getOrInitTagValues(tlvs, tag); values.push_back(value); } - } while (offset < static_cast(tlvStructure.size())); return tlvs; } -std::vector>& BerTlvUtil::getOrInitTagValues( +std::vector>& +BerTlvUtil::getOrInitTagValues( std::map>>& tlvs, const int tag) { const auto it = tlvs.find(tag); if (it == tlvs.end()) { - std::vector> values; - tlvs.insert({tag, values}); + std::vector> values; + tlvs.insert({tag, values}); } /* Look again and return reference */ return tlvs.find(tag)->second; } -int BerTlvUtil::getTagSize(const std::vector& tlvStructure, const int offset) +int +BerTlvUtil::getTagSize( + const std::vector& tlvStructure, const int offset) { /* C++: prevent accessing unexisting values */ if (offset >= static_cast(tlvStructure.size())) { @@ -185,23 +202,28 @@ int BerTlvUtil::getTagSize(const std::vector& tlvStructure, const int o } } -int BerTlvUtil::getTag(const std::vector& tlvStructure, const int offset, const int size) +int +BerTlvUtil::getTag( + const std::vector& tlvStructure, const int offset, const int size) { switch (size) { case 1: return tlvStructure[offset] & 0xFF; case 2: - return ((tlvStructure[offset] & 0xFF) << 8) + (tlvStructure[offset + 1] & 0xFF); + return ((tlvStructure[offset] & 0xFF) << 8) + + (tlvStructure[offset + 1] & 0xFF); case 3: return ((tlvStructure[offset] & 0xFF) << 16) - + ((tlvStructure[offset + 1] & 0xFF) << 8) - + (tlvStructure[offset + 2] & 0xFF); + + ((tlvStructure[offset + 1] & 0xFF) << 8) + + (tlvStructure[offset + 2] & 0xFF); default: throw IllegalArgumentException("Bad tag size."); } } -int BerTlvUtil::getLengthSize(const std::vector& tlvStructure, const int offset) +int +BerTlvUtil::getLengthSize( + const std::vector& tlvStructure, const int offset) { int firstByteLength = tlvStructure[offset] & 0xff; @@ -219,9 +241,9 @@ int BerTlvUtil::getLengthSize(const std::vector& tlvStructure, const in } } -int BerTlvUtil::getLength(const std::vector& tlvStructure, - const int offset, - const int size) +int +BerTlvUtil::getLength( + const std::vector& tlvStructure, const int offset, const int size) { switch (size) { case 1: @@ -229,12 +251,13 @@ int BerTlvUtil::getLength(const std::vector& tlvStructure, case 2: return tlvStructure[offset + 1] & 0xFF; case 3: - return ((tlvStructure[offset + 1] & 0xFF) << 8) + (tlvStructure[offset + 2] & 0xFF); + return ((tlvStructure[offset + 1] & 0xFF) << 8) + + (tlvStructure[offset + 2] & 0xFF); default: throw IllegalArgumentException("Bad length size."); } } -} -} -} +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/keyple/core/util/ByteArrayUtil.cpp b/src/main/keyple/core/util/ByteArrayUtil.cpp new file mode 100644 index 0000000..4edcd84 --- /dev/null +++ b/src/main/keyple/core/util/ByteArrayUtil.cpp @@ -0,0 +1,273 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include "keyple/core/util/ByteArrayUtil.hpp" + +#include +#include + +#include "keyple/core/util/HexUtil.hpp" +#include "keyple/core/util/KeypleAssert.hpp" +#include "keyple/core/util/cpp/Character.hpp" +#include "keyple/core/util/cpp/Pattern.hpp" +#include "keyple/core/util/cpp/StringBuilder.hpp" +#include "keyple/core/util/cpp/System.hpp" +#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp" +#include "keyple/core/util/cpp/exception/NegativeArraySizeException.hpp" + +namespace keyple { +namespace core { +namespace util { + +using keyple::core::util::cpp::System; +using keyple::core::util::cpp::exception::ArrayIndexOutOfBoundsException; +using keyple::core::util::cpp::exception::IllegalArgumentException; +using keyple::core::util::cpp::exception::NegativeArraySizeException; + +const std::vector +ByteArrayUtil::extractBytes( + const std::vector& src, const int bitOffset, const int nbBytes) +{ + if (bitOffset < 0) { + throw ArrayIndexOutOfBoundsException("negative index"); + } + + if (nbBytes < 0) { + throw NegativeArraySizeException("negative array size"); + } + + const int byteOffset = bitOffset / 8; + int lBitOffset = bitOffset % 8; + + if (byteOffset >= static_cast((src.size() - (lBitOffset ? 1 : 0)))) { + throw ArrayIndexOutOfBoundsException("pos + offset > src size"); + } + + std::vector dest(nbBytes); + + if (lBitOffset == 0) { + System::arraycopy(src, byteOffset, dest, 0, nbBytes); + } else { + const int rightShift = 8 - bitOffset; + for (int i = 0, j = byteOffset; j < byteOffset + nbBytes; i++, j++) { + dest[i] + = ((src[j] << lBitOffset) + | ((src[j + 1] & 0xFF) >> rightShift)); + } + } + + return dest; +} + +const std::vector +ByteArrayUtil::extractBytes(const uint64_t src, const int nbBytes) +{ + if (nbBytes < 0) { + throw NegativeArraySizeException("negative array size"); + } + + std::vector data(nbBytes); + int shift = 0; + int i = nbBytes - 1; + + while (i >= 0) { + data[i] = ((src >> shift) & 0xFF); + shift += 8; + i--; + } + + return data; +} + +uint16_t +ByteArrayUtil::extractShort(const std::vector& src, const int offset) +{ + if (offset < 0 || offset > static_cast(src.size() - 2)) { + throw ArrayIndexOutOfBoundsException( + "offset not in range [0...(src.size() - 2)"); + } + + return ((src[offset] & 0xFF) << 8) | (src[offset + 1] & 0xFF); +} + +uint32_t +ByteArrayUtil::extractInt( + const std::vector& src, + const int offset, + const int nbBytes, + const bool isSigned) +{ + if (offset < 0) { + throw ArrayIndexOutOfBoundsException("negative offset"); + } + + if ((offset + nbBytes) > static_cast(src.size())) { + throw ArrayIndexOutOfBoundsException("offset + nbBytes > src size"); + } + + /* C++ - doesn't make sense to have nbBytes > int size */ + if (nbBytes > 4) { + throw IllegalArgumentException("nbBytes can't be bigger than 4"); + } + + uint32_t val = 0; + uint32_t complement = 0xFFFFFFFF; + int lOffset = offset; + int lNbBytes = nbBytes; + bool negative = false; + + /* Check MSB byte negativeness */ + negative = src[lOffset] > 0x7F; + + /* Get value */ + while (lNbBytes > 0) { + val |= ((src[lOffset++] & 0xFF) << (8 * (--lNbBytes))); + complement &= ~( + 0xFF << 8 * lNbBytes); // cppcheck-suppress[integerOverflowCond] + } + + /* If signed, add complement */ + if (isSigned && negative) { + val |= complement; + } + + return val; +} + +uint64_t +ByteArrayUtil::extractLong( + const std::vector& src, + const int offset, + const int nbBytes, + const bool isSigned) +{ + int lOffset = offset; + int lNbBytes = nbBytes; + + if (lOffset < 0 || lOffset > static_cast(src.size() - lNbBytes)) { + throw ArrayIndexOutOfBoundsException( + "offset not in range [0...(src.size() - nbBytes)"); + } + + uint64_t val = 0L; + uint64_t complement = 0xFFFFFFFFFFFFFFFF; + bool negative = false; + + /* Get value */ + while (lNbBytes > 0) { + /* Check MSB byte negativeness */ + negative + = negative ? true : ((src[lOffset] & 0xFF) > 0x7F ? true : false); + val + |= ((static_cast(src[lOffset++] & 0xFF)) + << (8 * (--lNbBytes))); + complement &= ~((static_cast(0xFF)) << 8 * lNbBytes); + } + + /* If signed, add complement */ + if (isSigned && negative) { + val |= complement; + } + + return static_cast(val); +} + +void +ByteArrayUtil::copyBytes( + const uint64_t src, + std::vector& dest, + const int offset, + const int nbBytes) +{ + if (offset < 0 || offset > static_cast(dest.size() - nbBytes)) { + throw ArrayIndexOutOfBoundsException( + "offset not in range [0...(dest.size() - nbBytes)"); + } + + System::arraycopy(extractBytes(src, nbBytes), 0, dest, offset, nbBytes); +} + +bool +ByteArrayUtil::isValidHexString(const std::string& hex) +{ + return HexUtil::isValid(hex); +} + +const std::string +ByteArrayUtil::normalizeHexString(const std::string& hex) +{ + if (hex.length() % 2 != 0) { + return "0" + hex; + } + + return hex; +} + +std::vector +ByteArrayUtil::fromHex(const std::string& hex) +{ + Assert::getInstance() + .notEmpty(hex, "hex") + .isEqual(hex.length() % 2, 0, "hex size"); + + return HexUtil::toByteArray(hex); +} + +const std::string +ByteArrayUtil::toHex(const std::vector& src) +{ + if (src.empty()) { + return ""; + } + + return HexUtil::toHex(src); +} + +int +ByteArrayUtil::twoBytesToInt( + const std::vector& bytes, const int offset) +{ + return extractInt(bytes, offset, 2, false); +} + +int +ByteArrayUtil::twoBytesSignedToInt( + const std::vector& bytes, const int offset) +{ + return extractInt(bytes, offset, 2, true); +} + +int +ByteArrayUtil::threeBytesToInt( + const std::vector& bytes, const int offset) +{ + return extractInt(bytes, offset, 3, false); +} + +int +ByteArrayUtil::threeBytesSignedToInt( + const std::vector& bytes, const int offset) +{ + return extractInt(bytes, offset, 3, true); +} + +int +ByteArrayUtil::fourBytesToInt( + const std::vector& bytes, const int offset) +{ + return extractInt(bytes, offset, 4, true); +} + +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/keyple/core/util/HexUtil.cpp b/src/main/keyple/core/util/HexUtil.cpp new file mode 100644 index 0000000..49bf4de --- /dev/null +++ b/src/main/keyple/core/util/HexUtil.cpp @@ -0,0 +1,263 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include "keyple/core/util/HexUtil.hpp" + +#include +#include +#include + +#include "keyple/core/util/cpp/exception/StringIndexOutOfBoundsException.hpp" + +namespace keyple { +namespace core { +namespace util { + +using keyple::core::util::cpp::exception::StringIndexOutOfBoundsException; + +const std::vector HexUtil::mByteToHex + = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", + "0C", "0D", "0E", "0F", "10", "11", "12", "13", "14", "15", "16", "17", + "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", "20", "21", "22", "23", + "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", + "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", + "3C", "3D", "3E", "3F", "40", "41", "42", "43", "44", "45", "46", "47", + "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", "50", "51", "52", "53", + "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", + "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", + "6C", "6D", "6E", "6F", "70", "71", "72", "73", "74", "75", "76", "77", + "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", "80", "81", "82", "83", + "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", + "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", + "9C", "9D", "9E", "9F", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", + "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", "B0", "B1", "B2", "B3", + "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", + "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", + "CC", "CD", "CE", "CF", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", + "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", "E0", "E1", "E2", "E3", + "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", + "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", + "FC", "FD", "FE", "FF"}; + +const std::vector HexUtil::mHexToNibble = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, +}; + +HexUtil::HexUtil() +{ +} + +bool +HexUtil::isValid(const std::string& hex) +{ + if (hex.length() == 0 || hex.length() % 2 != 0) { + return false; + } + + for (int i = 0; i < static_cast(hex.size()); i++) { + if (mHexToNibble[hex.at(i)] == 0xFF) { + return false; + } + } + + return true; +} + +const std::vector +HexUtil::toByteArray(const std::string& hex) +{ + std::vector tab(hex.size() / 2); + + if (hex.length() % 2) { + throw StringIndexOutOfBoundsException("string has odd length"); + } + + for (int i = 0; i < static_cast(hex.length()); i += 2) { + tab[i / 2] + = ((mHexToNibble[hex.at(i)] << 4) + + (mHexToNibble[hex.at(i + 1)] & 0xFF)); + } + + return tab; +} + +uint8_t +HexUtil::toByte(const std::string& hex) +{ + uint8_t val = 0; + + for (int i = 0; i < static_cast(hex.length()); i++) { + val <<= 4; + val |= (mHexToNibble[hex.at(i)] & 0xFF); + } + + return val; +} + +uint16_t +HexUtil::toShort(const std::string& hex) +{ + uint16_t val = 0; + + for (int i = 0; i < static_cast(hex.length()); i++) { + val <<= 4; + val |= (mHexToNibble[hex.at(i)] & 0xFF); + } + + return val; +} + +uint32_t +HexUtil::toInt(const std::string& hex) +{ + uint32_t val = 0; + + for (int i = 0; i < static_cast(hex.length()); i++) { + val <<= 4; + val |= (mHexToNibble[hex.at(i)] & 0xFF); + } + + return val; +} + +uint64_t +HexUtil::toLong(const std::string& hex) +{ + uint64_t val = 0; + + for (int i = 0; i < static_cast(hex.length()); i++) { + val <<= 4; + val |= (mHexToNibble[hex.at(i)] & 0xFF); + } + + return val; +} + +const std::string +HexUtil::toHex(const std::vector& tab) +{ + std::stringstream ss; + + for (const auto& b : tab) { + ss << (mByteToHex[b & 0xFF]); + } + + return ss.str(); +} + +const std::string +HexUtil::toHex(const uint8_t val) +{ + return mByteToHex[val & 0xFF]; +} + +const std::string +HexUtil::toHex(const uint16_t val) +{ + if ((val & 0xFF00) == 0) { + return mByteToHex[val & 0xFF]; + } + + return mByteToHex[val >> 8 & 0xFF] + mByteToHex[val & 0xFF]; +} + +const std::string +HexUtil::toHex(const uint32_t val) +{ + if ((val & 0xFFFFFF00) == 0) { + return mByteToHex[val & 0xFF]; + } else if ((val & 0xFFFF0000) == 0) { + return mByteToHex[val >> 8 & 0xFF] + mByteToHex[val & 0xFF]; + } else if ((val & 0xFF000000) == 0) { + return mByteToHex[val >> 16 & 0xFF] + mByteToHex[val >> 8 & 0xFF] + + mByteToHex[val & 0xFF]; + } + + return mByteToHex[val >> 24 & 0xFF] + mByteToHex[val >> 16 & 0xFF] + + mByteToHex[val >> 8 & 0xFF] + mByteToHex[val & 0xFF]; +} + +const std::string +HexUtil::toHex(const uint64_t val) +{ + if ((val & 0xFFFFFFFFFFFFFF00L) == 0) { + return mByteToHex[static_cast((val & 0xFF))]; + } else if ((val & 0xFFFFFFFFFFFF0000L) == 0) { + return mByteToHex[static_cast((val >> 8 & 0xFF))] + + mByteToHex[static_cast((val & 0xFF))]; + } else if ((val & 0xFFFFFFFFFF000000L) == 0) { + return mByteToHex[static_cast((val >> 16 & 0xFF))] + + mByteToHex[static_cast((val >> 8 & 0xFF))] + + mByteToHex[static_cast((val & 0xFF))]; + } else if ((val & 0xFFFFFFFF00000000L) == 0) { + return mByteToHex[static_cast((val >> 24 & 0xFF))] + + mByteToHex[static_cast((val >> 16 & 0xFF))] + + mByteToHex[static_cast((val >> 8 & 0xFF))] + + mByteToHex[static_cast((val & 0xFF))]; + } else if ((val & 0xFFFFFF0000000000L) == 0) { + return mByteToHex[static_cast((val >> 32 & 0xFF))] + + mByteToHex[static_cast((val >> 24 & 0xFF))] + + mByteToHex[static_cast((val >> 16 & 0xFF))] + + mByteToHex[static_cast((val >> 8 & 0xFF))] + + mByteToHex[static_cast((val & 0xFF))]; + } else if ((val & 0xFFFF000000000000L) == 0) { + return mByteToHex[static_cast((val >> 40 & 0xFF))] + + mByteToHex[static_cast((val >> 32 & 0xFF))] + + mByteToHex[static_cast((val >> 24 & 0xFF))] + + mByteToHex[static_cast((val >> 16 & 0xFF))] + + mByteToHex[static_cast((val >> 8 & 0xFF))] + + mByteToHex[static_cast((val & 0xFF))]; + } else if ((val & 0xFF00000000000000L) == 0) { + return mByteToHex[static_cast((val >> 48 & 0xFF))] + + mByteToHex[static_cast((val >> 40 & 0xFF))] + + mByteToHex[static_cast((val >> 32 & 0xFF))] + + mByteToHex[static_cast((val >> 24 & 0xFF))] + + mByteToHex[static_cast((val >> 16 & 0xFF))] + + mByteToHex[static_cast((val >> 8 & 0xFF))] + + mByteToHex[static_cast((val & 0xFF))]; + } + + return mByteToHex[static_cast((val >> 56 & 0xFF))] + + mByteToHex[static_cast((val >> 48 & 0xFF))] + + mByteToHex[static_cast((val >> 40 & 0xFF))] + + mByteToHex[static_cast((val >> 32 & 0xFF))] + + mByteToHex[static_cast((val >> 24 & 0xFF))] + + mByteToHex[static_cast((val >> 16 & 0xFF))] + + mByteToHex[static_cast((val >> 8 & 0xFF))] + + mByteToHex[static_cast((val & 0xFF))]; +} + +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/keyple/core/util/KeypleAssert.cpp b/src/main/keyple/core/util/KeypleAssert.cpp new file mode 100644 index 0000000..11f67e4 --- /dev/null +++ b/src/main/keyple/core/util/KeypleAssert.cpp @@ -0,0 +1,137 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include "keyple/core/util/KeypleAssert.hpp" + +#include +#include + +#include "keyple/core/util/HexUtil.hpp" + +namespace keyple { +namespace core { +namespace util { + +const char* Assert::ARGUMENT = "Argument ["; +const char* Assert::CONDITION = "Condition ["; +const char* Assert::HAS_A_VALUE = "] has a value ["; +const char* Assert::LESS_THAN = "] less than ["; +const char* Assert::GREATER_THAN = "] greater than ["; +const char* Assert::IS_NULL = "] is null."; +const char* Assert::IS_EMPTY = "] is empty."; +const char* Assert::IS_FALSE = "] is false."; +const char* Assert::IS_NOT_HEX = "] is not a hex string."; +const char* Assert::NOT_EQUAL_TO = "] not equal to ["; +const char* Assert::CLOSING_BRACKET = "]."; + +Assert::Assert() +{ +} + +Assert& +Assert::getInstance() +{ + static Assert INSTANCE; + + return INSTANCE; +} + +Assert& +Assert::notEmpty(const std::string& obj, const std::string& name) +{ + if (obj == "") { + throw IllegalArgumentException(ARGUMENT + name + IS_EMPTY); + } + + return *this; +} + +Assert& +Assert::notEmpty(const std::vector& obj, const std::string& name) +{ + if (obj.size() == 0) { + throw IllegalArgumentException(ARGUMENT + name + IS_EMPTY); + } + + return *this; +} + +Assert& +Assert::isTrue(const bool condition, const std::string& name) +{ + if (!condition) { + throw IllegalArgumentException(CONDITION + name + IS_FALSE); + } + + return *this; +} + +Assert& +Assert::greaterOrEqual( + const size_t number, const size_t minValue, const std::string& name) +{ + if (number < minValue) { + throw IllegalArgumentException( + ARGUMENT + name + HAS_A_VALUE + std::to_string(number) + LESS_THAN + + std::to_string(minValue) + CLOSING_BRACKET); + } + + return *this; +} + +Assert& +Assert::isEqual( + const size_t number, const size_t value, const std::string& name) +{ + if (number != value) { + throw IllegalArgumentException( + ARGUMENT + name + HAS_A_VALUE + std::to_string(number) + + NOT_EQUAL_TO + std::to_string(value) + CLOSING_BRACKET); + } + + return *this; +} + +Assert& +Assert::isInRange( + const size_t number, + const size_t minValue, + const size_t maxValue, + const std::string& name) +{ + if (number < minValue) { + throw IllegalArgumentException( + ARGUMENT + name + HAS_A_VALUE + std::to_string(number) + LESS_THAN + + std::to_string(minValue) + CLOSING_BRACKET); + } else if (number > maxValue) { + throw IllegalArgumentException( + ARGUMENT + name + HAS_A_VALUE + std::to_string(number) + + GREATER_THAN + std::to_string(maxValue) + CLOSING_BRACKET); + } + + return *this; +} + +Assert& +Assert::isHexString(const std::string& hex, const std::string& name) +{ + if (!HexUtil::isValid(hex)) { + throw IllegalArgumentException(ARGUMENT + name + IS_NOT_HEX); + } + + return *this; +} + +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/keyple/core/util/cpp/Logger.cpp b/src/main/keyple/core/util/cpp/Logger.cpp new file mode 100644 index 0000000..f5089e6 --- /dev/null +++ b/src/main/keyple/core/util/cpp/Logger.cpp @@ -0,0 +1,77 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include "keyple/core/util/cpp/Logger.hpp" + +#include +#include +#include +#include +#include + +namespace keyple { +namespace core { +namespace util { +namespace cpp { + +Logger::Level Logger::mLevel = Logger::Level::logDebug; + +Logger::Logger(const std::string& className, std::mutex* mtx) +: className(demangle(className.c_str())) +, mtx(mtx) +{ +} + +std::string +Logger::getClassName() +{ + return className; +} + +void +Logger::setLoggerLevel(Logger::Level level) +{ + mLevel = level; +} + +const std::string +Logger::getCurrentTimestamp() +{ + using std::chrono::system_clock; + auto currentTime = std::chrono::system_clock::now(); + char buffer1[21]; + char buffer2[26]; + + auto transformed = currentTime.time_since_epoch().count() / 1000000; + auto millis = transformed % 1000; + + tm ttm; + std::time_t tt = system_clock::to_time_t(currentTime); +#if defined(WIN32) || defined(_WIN32) \ + || defined(__WIN32) && !defined(__CYGWIN__) + localtime_s(&ttm, &tt); +#else + localtime_r(&tt, &ttm); +#endif + + strftime(buffer1, sizeof(buffer1), "%F %H:%M:%S", &ttm); + snprintf( + buffer2, sizeof(buffer2), "%s:%03d", buffer1, static_cast(millis)); + + return std::string(buffer2); +} + +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/keyple/core/util/cpp/LoggerFactory.cpp b/src/main/keyple/core/util/cpp/LoggerFactory.cpp new file mode 100644 index 0000000..2da8f4b --- /dev/null +++ b/src/main/keyple/core/util/cpp/LoggerFactory.cpp @@ -0,0 +1,34 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include "keyple/core/util/cpp/LoggerFactory.hpp" + +#include + +namespace keyple { +namespace core { +namespace util { +namespace cpp { + +std::mutex LoggerFactory::mtx; + +std::unique_ptr +LoggerFactory::getLogger(const std::type_info& type) +{ + return std::unique_ptr(new Logger(type.name(), &mtx)); +} + +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/cpp/Matcher.cpp b/src/main/keyple/core/util/cpp/Matcher.cpp old mode 100755 new mode 100644 similarity index 53% rename from src/main/cpp/Matcher.cpp rename to src/main/keyple/core/util/cpp/Matcher.cpp index 4adc340..b9f64e8 --- a/src/main/cpp/Matcher.cpp +++ b/src/main/keyple/core/util/cpp/Matcher.cpp @@ -1,37 +1,41 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#include +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include #include +#include -#include "IndexOutOfBoundsException.h" -#include "Matcher.h" -#include "Pattern.h" +#include "keyple/core/util/cpp/Matcher.hpp" +#include "keyple/core/util/cpp/Pattern.hpp" +#include "keyple/core/util/cpp/exception/IndexOutOfBoundsException.hpp" namespace keyple { namespace core { namespace util { namespace cpp { -using namespace keyple::core::util::cpp::exception; +using keyple::core::util::cpp::exception::IndexOutOfBoundsException; Matcher::Matcher(const Pattern* parent, const std::string& text) -: mParentPattern(parent), mText(text) +: mParentPattern(parent) +, mText(text) { /* Put fields to initial states */ reset(); } -bool Matcher::match(const int from, const int anchor) const +bool +Matcher::match(const int from, const int anchor) const { (void)from; (void)anchor; @@ -42,21 +46,24 @@ bool Matcher::match(const int from, const int anchor) const return false; } -bool Matcher::matches() +bool +Matcher::matches() { return match(mFrom, ENDANCHOR); } -std::string Matcher::replaceAll(const std::string& replacement) const +std::string +Matcher::replaceAll(const std::string& replacement) const { - std::stringstream ss; + std::stringstream ss; - ss << std::regex_replace(mText, mParentPattern->mPattern, replacement); + ss << std::regex_replace(mText, mParentPattern->mPattern, replacement); - return ss.str(); + return ss.str(); } -bool Matcher::find() +bool +Matcher::find() { int nextSearchIndex = mLast; if (nextSearchIndex == mFirst) @@ -68,15 +75,16 @@ bool Matcher::find() /* If next search starts beyond region then it fails */ if (nextSearchIndex > mTo) { - //for (int i = 0; i < (int)groups.size(); i++) - // groups[i] = -1; + // for (int i = 0; i < (int)groups.size(); i++) + // groups[i] = -1; return false; } return search(nextSearchIndex); } -bool Matcher::find(const int start) +bool +Matcher::find(const int start) { int limit = getTextLength(); @@ -88,20 +96,23 @@ bool Matcher::find(const int start) return search(start); } -const std::string Matcher::group(const int group) const +const std::string +Matcher::group(const int group) const { - if (group < 0 || group > (int)mGroups.size()) + if (group < 0 || group > static_cast(mGroups.size())) throw IndexOutOfBoundsException("No group" + std::to_string(group)); return mGroups[group]; } -const std::string Matcher::group() const +const std::string +Matcher::group() const { return group(0); } -bool Matcher::search(const int from) +bool +Matcher::search(const int from) { mSubs = mText.substr(from, mText.length() - from); @@ -111,21 +122,22 @@ bool Matcher::search(const int from) return false; } -int Matcher::getTextLength() const +int +Matcher::getTextLength() const { return static_cast(mText.length()); } -Matcher* Matcher::reset() +Matcher* +Matcher::reset() { - mFirst = -1; - mLast = 0; + mFirst = -1; + mLast = 0; mOldLast = -1; - for (int i = 0; i < (int)mGroups.size(); i++) - ; //groups[i] = -1; - for (int i = 0; i < (int)mLocals.size(); i++) - mLocals[i] = -1; + for (int i = 0; i < static_cast(mGroups.size()); i++) { + } // groups[i] = -1; + for (int i = 0; i < static_cast(mLocals.size()); i++) mLocals[i] = -1; mLastAppendPosition = 0; mFrom = 0; @@ -134,7 +146,7 @@ Matcher* Matcher::reset() return this; } -} -} -} -} +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/keyple/core/util/cpp/Pattern.cpp b/src/main/keyple/core/util/cpp/Pattern.cpp new file mode 100644 index 0000000..f39f6ea --- /dev/null +++ b/src/main/keyple/core/util/cpp/Pattern.cpp @@ -0,0 +1,68 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include "keyple/core/util/cpp/Pattern.hpp" + +#include +#include + +#include "keyple/core/util/cpp/exception/PatternSyntaxException.hpp" + +namespace keyple { +namespace core { +namespace util { +namespace cpp { + +using keyple::core::util::cpp::exception::PatternSyntaxException; + +Pattern::Pattern(const std::string& pattern, const int flags) +: mPattern(pattern) +, mFlags(flags) +{ +} + +std::shared_ptr +Pattern::compile(const std::string& regularExpression, const int flags) const +{ + /* Compiler hack */ + (void)mFlags; + + try { + return std::make_shared(regularExpression, flags); + + } catch (const std::exception& e) { + throw PatternSyntaxException(e.what()); + } +} + +std::shared_ptr +Pattern::compile(const std::string& pattern) +{ + try { + return std::make_shared(pattern, 0); + + } catch (const std::exception& e) { + throw PatternSyntaxException(e.what()); + } +} + +std::shared_ptr +Pattern::matcher(const std::string& input) const +{ + return std::make_shared(this, input); +} + +} /* namespace cpp */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/keyple/core/util/protocol/ContactCardCommonProtocol.cpp b/src/main/keyple/core/util/protocol/ContactCardCommonProtocol.cpp new file mode 100644 index 0000000..2af26c7 --- /dev/null +++ b/src/main/keyple/core/util/protocol/ContactCardCommonProtocol.cpp @@ -0,0 +1,47 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include "keyple/core/util/protocol/ContactCardCommonProtocol.hpp" + +#include + +namespace keyple { +namespace core { +namespace util { +namespace protocol { + +const ContactCardCommonProtocol + ContactCardCommonProtocol::ISO_7816_3("ISO_7816_3"); +const ContactCardCommonProtocol + ContactCardCommonProtocol::ISO_7816_3_T0("ISO_7816_3_T0"); +const ContactCardCommonProtocol + ContactCardCommonProtocol::ISO_7816_3_T1("ISO_7816_3_T1"); +const ContactCardCommonProtocol + ContactCardCommonProtocol::INNOVATRON_HIGH_SPEED_PROTOCOL_SAM( + "INNOVATRON_HIGH_SPEED_PROTOCOL_SAM"); + +ContactCardCommonProtocol::ContactCardCommonProtocol(const std::string& name) +: mName(name) +{ +} + +const std::string& +ContactCardCommonProtocol::getName() const +{ + return mName; +} + +} // namespace protocol +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/keyple/core/util/protocol/ContactlessCardCommonProtocol.cpp b/src/main/keyple/core/util/protocol/ContactlessCardCommonProtocol.cpp new file mode 100644 index 0000000..3c5c8ee --- /dev/null +++ b/src/main/keyple/core/util/protocol/ContactlessCardCommonProtocol.cpp @@ -0,0 +1,52 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include "keyple/core/util/protocol/ContactlessCardCommonProtocol.hpp" + +#include + +namespace keyple { +namespace core { +namespace util { +namespace protocol { + +const ContactlessCardCommonProtocol + ContactlessCardCommonProtocol::ISO_14443_4("ISO_14443_4"); +const ContactlessCardCommonProtocol + ContactlessCardCommonProtocol::NFC_A_ISO_14443_3A("NFC_A_ISO_14443_3A"); +const ContactlessCardCommonProtocol + ContactlessCardCommonProtocol::NFC_B_ISO_14443_3B("NFC_B_ISO_14443_3B"); +const ContactlessCardCommonProtocol + ContactlessCardCommonProtocol::NFC_F_JIS_6319_4("NFC_F_JIS_6319_4"); +const ContactlessCardCommonProtocol + ContactlessCardCommonProtocol::NFC_V_ISO_15693("NFC_V_ISO_15693"); +const ContactlessCardCommonProtocol + ContactlessCardCommonProtocol::INNOVATRON_B_PRIME_CARD( + "INNOVATRON_B_PRIME_CARD"); + +ContactlessCardCommonProtocol::ContactlessCardCommonProtocol( + const std::string& name) +: mName(name) +{ +} + +const std::string& +ContactlessCardCommonProtocol::getName() const +{ + return mName; +} + +} /* namespace protocol */ +} /* namespace util */ +} /* namespace core */ +} /* namespace keyple */ diff --git a/src/main/protocol/ContactCardCommonProtocol.cpp b/src/main/protocol/ContactCardCommonProtocol.cpp deleted file mode 100644 index 61b36b4..0000000 --- a/src/main/protocol/ContactCardCommonProtocol.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#include "ContactCardCommonProtocol.h" - -namespace keyple { -namespace core { -namespace util { -namespace protocol { - -const ContactCardCommonProtocol ContactCardCommonProtocol::ISO_7816_3( - "ISO_7816_3"); -const ContactCardCommonProtocol ContactCardCommonProtocol::ISO_7816_3_T0( - "ISO_7816_3_T0"); -const ContactCardCommonProtocol ContactCardCommonProtocol::ISO_7816_3_T1( - "ISO_7816_3_T1"); -const ContactCardCommonProtocol ContactCardCommonProtocol::INNOVATRON_HIGH_SPEED_PROTOCOL_SAM( - "INNOVATRON_HIGH_SPEED_PROTOCOL_SAM"); - -ContactCardCommonProtocol::ContactCardCommonProtocol(const std::string& name) : mName(name) {} - -const std::string& ContactCardCommonProtocol::getName() const -{ - return mName; -} - -} -} -} -} diff --git a/src/main/protocol/ContactlessCardCommonProtocol.cpp b/src/main/protocol/ContactlessCardCommonProtocol.cpp deleted file mode 100644 index 987c1fe..0000000 --- a/src/main/protocol/ContactlessCardCommonProtocol.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association https://calypsonet.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ - -#include "ContactlessCardCommonProtocol.h" - -namespace keyple { -namespace core { -namespace util { -namespace protocol { - -const ContactlessCardCommonProtocol ContactlessCardCommonProtocol::ISO_14443_4( - "ISO_14443_4"); -const ContactlessCardCommonProtocol ContactlessCardCommonProtocol::NFC_A_ISO_14443_3A( - "NFC_A_ISO_14443_3A"); -const ContactlessCardCommonProtocol ContactlessCardCommonProtocol::NFC_B_ISO_14443_3B( - "NFC_B_ISO_14443_3B"); -const ContactlessCardCommonProtocol ContactlessCardCommonProtocol::NFC_F_JIS_6319_4( - "NFC_F_JIS_6319_4"); -const ContactlessCardCommonProtocol ContactlessCardCommonProtocol::NFC_V_ISO_15693( - "NFC_V_ISO_15693"); -const ContactlessCardCommonProtocol ContactlessCardCommonProtocol::INNOVATRON_B_PRIME_CARD( - "INNOVATRON_B_PRIME_CARD"); - -ContactlessCardCommonProtocol::ContactlessCardCommonProtocol(const std::string& name) -: mName(name) {} - -const std::string& ContactlessCardCommonProtocol::getName() const -{ - return mName; -} - -} -} -} -} diff --git a/src/test/ApduUtilTest.cpp b/src/test/ApduUtilTest.cpp index 112d1eb..67cd518 100644 --- a/src/test/ApduUtilTest.cpp +++ b/src/test/ApduUtilTest.cpp @@ -1,30 +1,31 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association * - * https://www.calypsonet-asso.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "ApduUtil.h" -#include "HexUtil.h" +#include "keyple/core/util/ApduUtil.hpp" +#include "keyple/core/util/HexUtil.hpp" -using namespace testing; - -using namespace keyple::core::util; +using keyple::core::util::ApduUtil; +using keyple::core::util::HexUtil; const uint8_t CLA = 0x11; const uint8_t INS = 0x22; -const uint8_t P1 = 0x33; -const uint8_t P2 = 0x44; +const uint8_t P1 = 0x33; +const uint8_t P2 = 0x44; const std::vector DATA_IN = {0x12, 0x34, 0x56, 0x78}; const uint8_t LE = 3; @@ -49,14 +50,16 @@ TEST(ApduUtilTest, build_whenDataInIsNull_shouldReturnCase2) TEST(ApduUtilTest, build_whenLeIsNull_shouldReturnCase3) { - std::vector apduCommand = ApduUtil::build(CLA, INS, P1, P2, DATA_IN); + std::vector apduCommand + = ApduUtil::build(CLA, INS, P1, P2, DATA_IN); ASSERT_EQ(apduCommand, CASE3); } TEST(ApduUtilTest, build_whenDataInAndLeAreNotNull_shouldReturnCase4) { - std::vector apduCommand = ApduUtil::build(CLA, INS, P1, P2, DATA_IN, LE); + std::vector apduCommand + = ApduUtil::build(CLA, INS, P1, P2, DATA_IN, LE); ASSERT_EQ(apduCommand, CASE4); } diff --git a/src/test/BerTlvUtilTest.cpp b/src/test/BerTlvUtilTest.cpp index 99031b9..6a9cf9f 100644 --- a/src/test/BerTlvUtilTest.cpp +++ b/src/test/BerTlvUtilTest.cpp @@ -1,40 +1,42 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association * - * https://www.calypsonet-asso.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include +#include #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "BerTlvUtil.h" - -/* Keyple Core Util */ -#include "Arrays.h" -#include "HexUtil.h" -#include "IllegalArgumentException.h" - -using namespace testing; - -using namespace keyple::core::util; -using namespace keyple::core::util::cpp; -using namespace keyple::core::util::cpp::exception; - -const std::string TLV1 = - "6F238409315449432E49434131A516BF0C13C708000000001122334453070A3C2005141001"; -const std::string TLV2 = - "6F23A516BF0C1353070A3C2005141001C70800000000112233448409315449432E49434131"; - -static bool mapContainsEntry(const std::map>& m, - const int tag, - const std::vector& value) +#include "keyple/core/util/BerTlvUtil.hpp" +#include "keyple/core/util/HexUtil.hpp" +#include "keyple/core/util/cpp/Arrays.hpp" +#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp" + +using keyple::core::util::BerTlvUtil; +using keyple::core::util::HexUtil; +using keyple::core::util::cpp::Arrays; +using keyple::core::util::cpp::exception::IllegalArgumentException; + +const char* TLV1 = "6F238409315449432E49434131A516BF0C13C7080000000011223344530" + "70A3C2005141001"; +const char* TLV2 = "6F23A516BF0C1353070A3C2005141001C70800000000112233448409315" + "449432E49434131"; + +static bool +mapContainsEntry( + const std::map>& m, + const int tag, + const std::vector& value) { const auto it = m.find(tag); if (it != m.end() && it->second == value) { @@ -44,21 +46,20 @@ static bool mapContainsEntry(const std::map>>& m, - const std::vector& values) +static bool +mapContainsOnlyKeys( + const std::map>>& m, + const std::vector& values) { - for (const auto& entry : m) { - /* Check entry key belongs to values */ - if (!Arrays::contains(values, entry.first)) { - return false; - } - } - - return true; + return std::all_of(m.begin(), m.end(), [&](const auto& entry) { + return Arrays::contains(values, entry.first); + }); } -static bool vectorContainsExactly(std::vector>& v, - const std::vector>& values) +static bool +vectorContainsExactly( + std::vector>& v, + const std::vector>& values) { if (v.size() != values.size()) { return false; @@ -73,8 +74,9 @@ static bool vectorContainsExactly(std::vector>& v, return true; } -static bool vectorContainsExactly(std::vector>& v, - const std::vector& value) +static bool +vectorContainsExactly( + std::vector>& v, const std::vector& value) { if (v.size() != 1) { return false; @@ -83,91 +85,149 @@ static bool vectorContainsExactly(std::vector>& v, return Arrays::equals(v[0], value); } -TEST(BerTlvUtilTest, parse_whenStructureIsValidAndPrimitiveOnlyIsFalse_shouldProvideAllTags) +TEST( + BerTlvUtilTest, + parse_whenStructureIsValidAndPrimitiveOnlyIsFalse_shouldProvideAllTags) { auto tlvs = BerTlvUtil::parse(HexUtil::toByteArray(TLV1), false); - ASSERT_TRUE(mapContainsOnlyKeys(tlvs, {0x6F, 0x84, 0xA5, 0xBF0C, 0x53, 0xC7})); - - ASSERT_TRUE(vectorContainsExactly(tlvs[0x6F], HexUtil::toByteArray("8409315449432E49434131A516BF0C13C708000000001122334453070A3C2005141001"))); - ASSERT_TRUE(vectorContainsExactly(tlvs[0x84], HexUtil::toByteArray("315449432E49434131"))); - ASSERT_TRUE(vectorContainsExactly(tlvs[0xA5], HexUtil::toByteArray("BF0C13C708000000001122334453070A3C2005141001"))); - ASSERT_TRUE(vectorContainsExactly(tlvs[0xBF0C], HexUtil::toByteArray("C708000000001122334453070A3C2005141001"))); - ASSERT_TRUE(vectorContainsExactly(tlvs[0x53], HexUtil::toByteArray("0A3C2005141001"))); - ASSERT_TRUE(vectorContainsExactly(tlvs[0xC7], HexUtil::toByteArray("0000000011223344"))); + ASSERT_TRUE( + mapContainsOnlyKeys(tlvs, {0x6F, 0x84, 0xA5, 0xBF0C, 0x53, 0xC7})); + + ASSERT_TRUE(vectorContainsExactly( + tlvs[0x6F], + HexUtil::toByteArray("8409315449432E49434131A516BF0C13C708000" + "000001122334453070A3C2005141001"))); + ASSERT_TRUE(vectorContainsExactly( + tlvs[0x84], HexUtil::toByteArray("315449432E49434131"))); + ASSERT_TRUE(vectorContainsExactly( + tlvs[0xA5], + HexUtil::toByteArray("BF0C13C708000000001122334453070A3C2005141001"))); + ASSERT_TRUE(vectorContainsExactly( + tlvs[0xBF0C], + HexUtil::toByteArray("C708000000001122334453070A3C2005141001"))); + ASSERT_TRUE(vectorContainsExactly( + tlvs[0x53], HexUtil::toByteArray("0A3C2005141001"))); + ASSERT_TRUE(vectorContainsExactly( + tlvs[0xC7], HexUtil::toByteArray("0000000011223344"))); } -TEST(BerTlvUtilTest, parse_whenStructureIsValidAndPrimitiveOnlyIsFalse_shouldProvideAllTags2) +TEST( + BerTlvUtilTest, + parse_whenStructureIsValidAndPrimitiveOnlyIsFalse_shouldProvideAllTags2) { - auto tlvs = BerTlvUtil::parse(HexUtil::toByteArray("E030C106200107021D01C106202009021D04C106206919091D01C106201008041D03C10620401D021D01C10620501E021D01"), false); + auto tlvs = BerTlvUtil::parse( + HexUtil::toByteArray( + "E030C106200107021D01C106202009021D04C106206919091D0" + "1C106201008041D03C10620401D021D01C10620501E021D01"), + false); ASSERT_TRUE(mapContainsOnlyKeys(tlvs, {0xE0, 0xC1})); - ASSERT_TRUE(vectorContainsExactly(tlvs[0xE0], HexUtil::toByteArray("C106200107021D01C106202009021D04C106206919091D01C106201008041D03C10620401D021D01C10620501E021D01"))); - ASSERT_TRUE(vectorContainsExactly(tlvs[0xC1], { HexUtil::toByteArray("200107021D01"), - HexUtil::toByteArray("202009021D04"), - HexUtil::toByteArray("206919091D01"), - HexUtil::toByteArray("201008041D03"), - HexUtil::toByteArray("20401D021D01"), - HexUtil::toByteArray("20501E021D01") })); + ASSERT_TRUE(vectorContainsExactly( + tlvs[0xE0], + HexUtil::toByteArray( + "C106200107021D01C106202009021D04C106206919091D01C10" + "6201008041D03C10620401D021D01C10620501E021D01"))); + ASSERT_TRUE(vectorContainsExactly( + tlvs[0xC1], + {HexUtil::toByteArray("200107021D01"), + HexUtil::toByteArray("202009021D04"), + HexUtil::toByteArray("206919091D01"), + HexUtil::toByteArray("201008041D03"), + HexUtil::toByteArray("20401D021D01"), + HexUtil::toByteArray("20501E021D01")})); } -TEST(BerTlvUtilTest, parseSimple_whenStructureIsValidAndPrimitiveOnlyIsFalse_shouldProvideAllTags) +TEST( + BerTlvUtilTest, + parseSimple_whenStructureIsValidAndPrimitiveOnlyIsFalse_shouldProvideAllTags) // NOLINT { - const auto tlvs = BerTlvUtil::parseSimple(HexUtil::toByteArray(TLV1), false); + const auto tlvs + = BerTlvUtil::parseSimple(HexUtil::toByteArray(TLV1), false); ASSERT_EQ(tlvs.size(), 6); - ASSERT_TRUE(mapContainsEntry(tlvs, 0x6F, HexUtil::toByteArray("8409315449432E49434131A516BF0C13C708000000001122334453070A3C2005141001"))); - ASSERT_TRUE(mapContainsEntry(tlvs, 0x84, HexUtil::toByteArray("315449432E49434131"))); - ASSERT_TRUE(mapContainsEntry(tlvs, 0xA5, HexUtil::toByteArray("BF0C13C708000000001122334453070A3C2005141001"))); - ASSERT_TRUE(mapContainsEntry(tlvs, 0xBF0C, HexUtil::toByteArray("C708000000001122334453070A3C2005141001"))); - ASSERT_TRUE(mapContainsEntry(tlvs, 0x53, HexUtil::toByteArray("0A3C2005141001"))); - ASSERT_TRUE(mapContainsEntry(tlvs, 0xC7, HexUtil::toByteArray("0000000011223344"))); + ASSERT_TRUE(mapContainsEntry( + tlvs, + 0x6F, + HexUtil::toByteArray( + "8409315449432E49434131A516BF0C13C708000000001122334" + "453070A3C2005141001"))); + ASSERT_TRUE(mapContainsEntry( + tlvs, 0x84, HexUtil::toByteArray("315449432E49434131"))); + ASSERT_TRUE(mapContainsEntry( + tlvs, + 0xA5, + HexUtil::toByteArray("BF0C13C708000000001122334453070A3C2005141001"))); + ASSERT_TRUE(mapContainsEntry( + tlvs, + 0xBF0C, + HexUtil::toByteArray("C708000000001122334453070A3C2005141001"))); + ASSERT_TRUE( + mapContainsEntry(tlvs, 0x53, HexUtil::toByteArray("0A3C2005141001"))); + ASSERT_TRUE( + mapContainsEntry(tlvs, 0xC7, HexUtil::toByteArray("0000000011223344"))); } -TEST(BerTlvUtilTest, - parse_whenStructureIsValidAndPrimitiveOnlyIsTrue_shouldProvideOnlyPrimitiveTags) +TEST( + BerTlvUtilTest, + parse_whenStructureIsValidAndPrimitiveOnlyIsTrue_shouldProvideOnlyPrimitiveTags) // NOLINT { const auto tlvs = BerTlvUtil::parseSimple(HexUtil::toByteArray(TLV1), true); ASSERT_EQ(tlvs.size(), 3); - ASSERT_TRUE(mapContainsEntry(tlvs, 0x84, HexUtil::toByteArray("315449432E49434131"))); - ASSERT_TRUE(mapContainsEntry(tlvs, 0x53, HexUtil::toByteArray("0A3C2005141001"))); - ASSERT_TRUE(mapContainsEntry(tlvs, 0xC7, HexUtil::toByteArray("0000000011223344"))); + ASSERT_TRUE(mapContainsEntry( + tlvs, 0x84, HexUtil::toByteArray("315449432E49434131"))); + ASSERT_TRUE( + mapContainsEntry(tlvs, 0x53, HexUtil::toByteArray("0A3C2005141001"))); + ASSERT_TRUE( + mapContainsEntry(tlvs, 0xC7, HexUtil::toByteArray("0000000011223344"))); } TEST(BerTlvUtilTest, parseSimple_whenTagsOrderChange_shouldProvideTheSameTags) { - const auto tlvs1 = BerTlvUtil::parseSimple(HexUtil::toByteArray(TLV1), true); - const auto tlvs2 = BerTlvUtil::parseSimple(HexUtil::toByteArray(TLV2), true); + const auto tlvs1 + = BerTlvUtil::parseSimple(HexUtil::toByteArray(TLV1), true); + const auto tlvs2 + = BerTlvUtil::parseSimple(HexUtil::toByteArray(TLV2), true); ASSERT_EQ(tlvs1, tlvs2); } TEST(BerTlvUtilTest, parseSimple_whenTagsIdIs3Bytes_shouldProvideTheTag) { - const auto tlvs = BerTlvUtil::parseSimple(HexUtil::toByteArray("6F258409315449432E49434131A518BF0C15DFEF2C08000000001122334453070A3C2005141001"), true); + const auto tlvs = BerTlvUtil::parseSimple( + HexUtil::toByteArray( + "6F258409315449432E49434131A518BF0C15DFEF2C080000000" + "01122334453070A3C2005141001"), + true); ASSERT_EQ(tlvs.size(), 3); - ASSERT_TRUE(mapContainsEntry(tlvs, 0x84, HexUtil::toByteArray("315449432E49434131"))); - ASSERT_TRUE(mapContainsEntry(tlvs, 0x53, HexUtil::toByteArray("0A3C2005141001"))); - ASSERT_TRUE(mapContainsEntry(tlvs, 0xDFEF2C, HexUtil::toByteArray("0000000011223344"))); + ASSERT_TRUE(mapContainsEntry( + tlvs, 0x84, HexUtil::toByteArray("315449432E49434131"))); + ASSERT_TRUE( + mapContainsEntry(tlvs, 0x53, HexUtil::toByteArray("0A3C2005141001"))); + ASSERT_TRUE(mapContainsEntry( + tlvs, 0xDFEF2C, HexUtil::toByteArray("0000000011223344"))); } TEST(BerTlvUtilTest, parseSimple_whenStructureIsInvalid_shouldIAE) { - EXPECT_THROW(BerTlvUtil::parseSimple(HexUtil::toByteArray("6F23A5"), true), - IllegalArgumentException); + EXPECT_THROW( + BerTlvUtil::parseSimple(HexUtil::toByteArray("6F23A5"), true), + IllegalArgumentException); } TEST(BerTlvUtilTest, parseSimple_whenLengthFieldIsInvalid_shouldIAE) { - EXPECT_THROW(BerTlvUtil::parseSimple(HexUtil::toByteArray("6F83A5"), true), - IllegalArgumentException); + EXPECT_THROW( + BerTlvUtil::parseSimple(HexUtil::toByteArray("6F83A5"), true), + IllegalArgumentException); } TEST(BerTlvUtilTest, parseSimple_whenLengthIsZero_shouldReturnEmptyValue) { - const auto tlvs = BerTlvUtil::parseSimple(HexUtil::toByteArray("8400"), false); + const auto tlvs + = BerTlvUtil::parseSimple(HexUtil::toByteArray("8400"), false); const auto it = tlvs.find(0x84); ASSERT_NE(it, tlvs.end()); @@ -183,7 +243,7 @@ TEST(BerTlvUtilTest, parseSimple_whenLengthIsTwoBytes_shouldValue) tlv[1] = 0x81; tlv[2] = 250; for (int i = 3; i < 253; i++) { - tlv[i] = 0xA5; + tlv[i] = 0xA5; } const auto tlvs = BerTlvUtil::parseSimple(tlv, false); @@ -251,5 +311,6 @@ TEST(BerTlvUtilTest, isConstructed_whenTagIsNegative_shouldIAE) TEST(BerTlvUtilTest, isConstructed_whenTagIsTooLarge_shouldIAE) { - EXPECT_THROW(BerTlvUtil::isConstructed(0x1000000), IllegalArgumentException); + EXPECT_THROW( + BerTlvUtil::isConstructed(0x1000000), IllegalArgumentException); } diff --git a/src/test/ByteArrayUtilTest.cpp b/src/test/ByteArrayUtilTest.cpp index e3df9d0..9895ad7 100644 --- a/src/test/ByteArrayUtilTest.cpp +++ b/src/test/ByteArrayUtilTest.cpp @@ -1,164 +1,233 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association * - * https://www.calypsonet-asso.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include +#include #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "ByteArrayUtil.h" - -/* Keyple Core Util */ -#include "Arrays.h" -#include "ArrayIndexOutOfBoundsException.h" -#include "IllegalArgumentException.h" -#include "NegativeArraySizeException.h" - -using namespace testing; - -using namespace keyple::core::util; -using namespace keyple::core::util::cpp; -using namespace keyple::core::util::cpp::exception; - -const std::string HEXSTRING_ODD = "0102030"; -const std::string HEXSTRING_BAD = "010203ABGH8+"; -const std::string HEXSTRING_GOOD = "1234567890ABCDEFFEDCBA0987654321"; +#include "keyple/core/util/ByteArrayUtil.hpp" +#include "keyple/core/util/cpp/Arrays.hpp" +#include "keyple/core/util/cpp/exception/ArrayIndexOutOfBoundsException.hpp" +#include "keyple/core/util/cpp/exception/IllegalArgumentException.hpp" +#include "keyple/core/util/cpp/exception/NegativeArraySizeException.hpp" + +using keyple::core::util::ByteArrayUtil; +using keyple::core::util::cpp::Arrays; +using keyple::core::util::cpp::exception::ArrayIndexOutOfBoundsException; +using keyple::core::util::cpp::exception::IllegalArgumentException; +using keyple::core::util::cpp::exception::NegativeArraySizeException; + +const char* HEXSTRING_ODD = "0102030"; +const char* HEXSTRING_BAD = "010203ABGH8+"; +const char* HEXSTRING_GOOD = "1234567890ABCDEFFEDCBA0987654321"; const std::vector BYTEARRAY_LEN_0 = {}; const std::vector BYTEARRAY_LEN_1 = {0x12}; const std::vector BYTEARRAY_LEN_2 = {0x12, 0x34}; const std::vector BYTEARRAY_LEN_3 = {0x12, 0x34, 0x56}; const std::vector BYTEARRAY_LEN_4 = {0x12, 0x34, 0x56, 0x78}; -const std::vector BYTEARRAY_LEN_16 = { - 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x09, 0x87, 0x65, 0x43, 0x21 -}; +const std::vector BYTEARRAY_LEN_16 + = {0x12, + 0x34, + 0x56, + 0x78, + 0x90, + 0xAB, + 0xCD, + 0xEF, + 0xFE, + 0xDC, + 0xBA, + 0x09, + 0x87, + 0x65, + 0x43, + 0x21}; - -TEST(ByteArrayUtilTest, extractBytes_byteArray_whenBitOffsetIsOutOfRange_shouldThrowAIOOBE) +TEST( + ByteArrayUtilTest, + extractBytes_byteArray_whenBitOffsetIsOutOfRange_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractBytes(std::vector(1), 16, 1), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractBytes(std::vector(1), 16, 1), + ArrayIndexOutOfBoundsException); } -TEST(ByteArrayUtilTest, extractBytes_byteArray_whenBitOffsetIsOutOfRange_shouldThrowAIOOBE2) +TEST( + ByteArrayUtilTest, + extractBytes_byteArray_whenBitOffsetIsOutOfRange_shouldThrowAIOOBE2) { - EXPECT_THROW(ByteArrayUtil::extractBytes(std::vector(1), 9, 1), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractBytes(std::vector(1), 9, 1), + ArrayIndexOutOfBoundsException); } -TEST(ByteArrayUtilTest, extractBytes_byteArray_whenBitOffsetIsNegative_shouldThrowAIOOBE) +TEST( + ByteArrayUtilTest, + extractBytes_byteArray_whenBitOffsetIsNegative_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractBytes(std::vector(1), -8, 1), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractBytes(std::vector(1), -8, 1), + ArrayIndexOutOfBoundsException); } -TEST(ByteArrayUtilTest, extractBytes_byteArray_whenBitOffsetIsNegative_shouldThrowAIOOBE2) +TEST( + ByteArrayUtilTest, + extractBytes_byteArray_whenBitOffsetIsNegative_shouldThrowAIOOBE2) { - EXPECT_THROW(ByteArrayUtil::extractBytes(std::vector(1), -1, 1), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractBytes(std::vector(1), -1, 1), + ArrayIndexOutOfBoundsException); } - -TEST(ByteArrayUtilTest, extractBytes_byteArray_whenNbBytesIsOutOfRange_shouldThrowAIOOBE) +TEST( + ByteArrayUtilTest, + extractBytes_byteArray_whenNbBytesIsOutOfRange_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractBytes(std::vector(1), 0, 2), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractBytes(std::vector(1), 0, 2), + ArrayIndexOutOfBoundsException); } -TEST(ByteArrayUtilTest, extractBytes_byteArray_whenNbBytesIsOutOfRange_shouldThrowAIOOBE2) +TEST( + ByteArrayUtilTest, + extractBytes_byteArray_whenNbBytesIsOutOfRange_shouldThrowAIOOBE2) { - EXPECT_THROW(ByteArrayUtil::extractBytes(std::vector(1), 1, 2), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractBytes(std::vector(1), 1, 2), + ArrayIndexOutOfBoundsException); } -TEST(ByteArrayUtilTest, extractBytes_byteArray_whenNbBytesIsNegative_shouldThrowAIOOBE) +TEST( + ByteArrayUtilTest, + extractBytes_byteArray_whenNbBytesIsNegative_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractBytes(std::vector(1), 0, -1), - NegativeArraySizeException); + EXPECT_THROW( + ByteArrayUtil::extractBytes(std::vector(1), 0, -1), + NegativeArraySizeException); } -TEST(ByteArrayUtilTest, extractBytes_byteArray_whenNbBytesIsNegative_shouldThrowAIOOBE2) +TEST( + ByteArrayUtilTest, + extractBytes_byteArray_whenNbBytesIsNegative_shouldThrowAIOOBE2) { - EXPECT_THROW(ByteArrayUtil::extractBytes(std::vector(1), 1, -1), - NegativeArraySizeException); + EXPECT_THROW( + ByteArrayUtil::extractBytes(std::vector(1), 1, -1), + NegativeArraySizeException); } - -TEST(ByteArrayUtilTest, extractBytes_byteArray_whenBitOffsetIsMultipleOf8_shouldBeSuccessful) +TEST( + ByteArrayUtilTest, + extractBytes_byteArray_whenBitOffsetIsMultipleOf8_shouldBeSuccessful) { const std::vector src = {0xF1, 0xF2, 0xF3}; ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(src, 8, 1), {0xF2})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(src, 8, 2), {0xF2, 0xF3})); + ASSERT_TRUE( + Arrays::equals(ByteArrayUtil::extractBytes(src, 8, 2), {0xF2, 0xF3})); } -TEST(ByteArrayUtilTest, extractBytes_byteArray_whenBitOffsetIsNotMultipleOf8_shouldBeSuccessful) +TEST( + ByteArrayUtilTest, + extractBytes_byteArray_whenBitOffsetIsNotMultipleOf8_shouldBeSuccessful) { const std::vector src = {0xF1, 0xF2, 0xF3}; ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(src, 6, 1), {0x7C})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(src, 6, 2), {0x7C, 0xBC})); + ASSERT_TRUE( + Arrays::equals(ByteArrayUtil::extractBytes(src, 6, 2), {0x7C, 0xBC})); ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(src, 3, 1), {0x8F})); } -TEST(ByteArrayUtilTest, extractBytes_number_AndNbBytesIsNegative_shouldThrowNASE) +TEST( + ByteArrayUtilTest, extractBytes_number_AndNbBytesIsNegative_shouldThrowNASE) { - EXPECT_THROW(ByteArrayUtil::extractBytes(0, -1), NegativeArraySizeException); + EXPECT_THROW( + ByteArrayUtil::extractBytes(0, -1), NegativeArraySizeException); } -TEST(ByteArrayUtilTest, extractBytes_number_AndNbBytesIs0_shouldReturnAnEmptyArray) +TEST( + ByteArrayUtilTest, + extractBytes_number_AndNbBytesIs0_shouldReturnAnEmptyArray) { ASSERT_EQ(ByteArrayUtil::extractBytes(0xFF223344, 0).size(), 0); } -TEST(ByteArrayUtilTest, extractBytes_number_AndNbBytesIs1to8_shouldExtractLastBytes) +TEST( + ByteArrayUtilTest, + extractBytes_number_AndNbBytesIs1to8_shouldExtractLastBytes) { /* Short */ const uint16_t shortNumber = 0xFF22; - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(shortNumber, 1), {0x22})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(shortNumber, 2), {0xFF, 0x22})); + ASSERT_TRUE( + Arrays::equals(ByteArrayUtil::extractBytes(shortNumber, 1), {0x22})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(shortNumber, 2), {0xFF, 0x22})); /* Integer */ const int intNumber = 0xFF223344; - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(intNumber, 1), {0x44})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(intNumber, 2), {0x33, 0x44})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(intNumber, 3), {0x22, 0x33, 0x44})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(intNumber, 4), {0xFF, 0x22, 0x33, 0x44})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(static_cast(intNumber), 1), + {0x44})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(static_cast(intNumber), 2), + {0x33, 0x44})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(static_cast(intNumber), 3), + {0x22, 0x33, 0x44})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(static_cast(intNumber), 4), + {0xFF, 0x22, 0x33, 0x44})); /* Long */ const uint64_t longNumber = 0xFF22334455667788L; - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(longNumber, 1), {0x88})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(longNumber, 2), {0x77, 0x88})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(longNumber, 3), {0x66, 0x77, 0x88})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(longNumber, 4), - {0x55, 0x66, 0x77, 0x88})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(longNumber, 5), - {0x44, 0x55, 0x66, 0x77, 0x88})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(longNumber, 6), - {0x33, 0x44, 0x55, 0x66, 0x77, 0x88})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(longNumber, 7), - {0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88})); - ASSERT_TRUE(Arrays::equals(ByteArrayUtil::extractBytes(longNumber, 8), - {0xFF, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88})); + ASSERT_TRUE( + Arrays::equals(ByteArrayUtil::extractBytes(longNumber, 1), {0x88})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(longNumber, 2), {0x77, 0x88})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(longNumber, 3), {0x66, 0x77, 0x88})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(longNumber, 4), {0x55, 0x66, 0x77, 0x88})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(longNumber, 5), + {0x44, 0x55, 0x66, 0x77, 0x88})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(longNumber, 6), + {0x33, 0x44, 0x55, 0x66, 0x77, 0x88})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(longNumber, 7), + {0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88})); + ASSERT_TRUE(Arrays::equals( + ByteArrayUtil::extractBytes(longNumber, 8), + {0xFF, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88})); } TEST(ByteArrayUtilTest, extractShort_whenOffsetIsNegative_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractShort(std::vector(2), -1), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractShort(std::vector(2), -1), + ArrayIndexOutOfBoundsException); } -TEST(ByteArrayUtilTest, extractShort_whenOffsetIsGreaterThanSrcLengthMinus2_shouldThrowAIOOBE) +TEST( + ByteArrayUtilTest, + extractShort_whenOffsetIsGreaterThanSrcLengthMinus2_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractShort(std::vector(2), 1), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractShort(std::vector(2), 1), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, extractShort_whenInputIsOk_shouldBeSuccessful) @@ -171,20 +240,25 @@ TEST(ByteArrayUtilTest, extractShort_whenInputIsOk_shouldBeSuccessful) TEST(ByteArrayUtilTest, extractInt_whenOffsetIsNegative_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractInt(std::vector(1), -1, 1, true), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractInt(std::vector(1), -1, 1, true), + ArrayIndexOutOfBoundsException); } -TEST(ByteArrayUtilTest, extractInt_whenOffsetIsGreaterThanSrcLengthMinusNbBytes_shouldThrowAIOOBE) +TEST( + ByteArrayUtilTest, + extractInt_whenOffsetIsGreaterThanSrcLengthMinusNbBytes_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractInt(std::vector(1), 1, 1, true), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractInt(std::vector(1), 1, 1, true), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, extractInt_whenNbBytesIsTooBig_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractInt(std::vector(1), 0, 2, true), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractInt(std::vector(1), 0, 2, true), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, extractInt_whenInputIsOk_shouldBeSuccessful) @@ -203,25 +277,31 @@ TEST(ByteArrayUtilTest, extractInt_whenInputIsOk_shouldBeSuccessful) TEST(ByteArrayUtilTest, extractLong_whenOffsetIsNegative_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractLong(std::vector(1), -1, 1, true), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractLong(std::vector(1), -1, 1, true), + ArrayIndexOutOfBoundsException); } -TEST(ByteArrayUtilTest, extractLong_whenOffsetIsGreaterThanSrcLengthMinusNbBytes_shouldThrowAIOOBE) +TEST( + ByteArrayUtilTest, + extractLong_whenOffsetIsGreaterThanSrcLengthMinusNbBytes_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractLong(std::vector(1), 1, 1, true), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractLong(std::vector(1), 1, 1, true), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, extractLong_whenNbBytesIsTooBig_shouldThrowAIOOBE) { - EXPECT_THROW(ByteArrayUtil::extractLong(std::vector(1), 0, 2, true), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::extractLong(std::vector(1), 0, 2, true), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, extractLong_whenInputIsOk_shouldBeSuccessful) { - const std::vector src = {0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA}; + const std::vector src + = {0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA}; ASSERT_EQ(ByteArrayUtil::extractLong(src, 1, 1, true), 0xFFFFFFFFFFFFFFF2L); ASSERT_EQ(ByteArrayUtil::extractLong(src, 1, 1, false), 0xF2L); @@ -238,7 +318,8 @@ TEST(ByteArrayUtilTest, extractLong_whenInputIsOk_shouldBeSuccessful) ASSERT_EQ(ByteArrayUtil::extractLong(src, 1, 7, true), 0xFFF2F3F4F5F6F7F8L); ASSERT_EQ(ByteArrayUtil::extractLong(src, 1, 7, false), 0xF2F3F4F5F6F7F8L); ASSERT_EQ(ByteArrayUtil::extractLong(src, 1, 8, true), 0xF2F3F4F5F6F7F8F9L); - ASSERT_EQ(ByteArrayUtil::extractLong(src, 1, 8, false), 0xF2F3F4F5F6F7F8F9L); + ASSERT_EQ( + ByteArrayUtil::extractLong(src, 1, 8, false), 0xF2F3F4F5F6F7F8F9L); } // C++: irrelevant, vector can't be null @@ -259,35 +340,44 @@ TEST(ByteArrayUtilTest, copyBytes_whenOffsetIsNegative_shouldThrow) { std::vector dest(1); - EXPECT_THROW(ByteArrayUtil::copyBytes(0, dest, -1, 0), ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::copyBytes(0, dest, -1, 0), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, copyBytes_whenNbBytesIsNegative_shouldThrow) { std::vector dest(1); - EXPECT_THROW(ByteArrayUtil::copyBytes(0, dest, 0, -1), NegativeArraySizeException); + EXPECT_THROW( + ByteArrayUtil::copyBytes(0, dest, 0, -1), NegativeArraySizeException); } TEST(ByteArrayUtilTest, copyBytes_whenOffsetIsOutOfRange_shouldThrowAIOOBE) { std::vector dest(1); - EXPECT_THROW(ByteArrayUtil::copyBytes(0, dest, 1, 1), ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::copyBytes(0, dest, 1, 1), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, copyBytes_whenNbBytesIsOutOfRange_shouldThrow) { std::vector dest(1); - EXPECT_THROW(ByteArrayUtil::copyBytes(0, dest, 0, 2), ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::copyBytes(0, dest, 0, 2), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, copyBytes_whenOffsetAndNbBytesIsOutOfRange_shouldThrow) { std::vector dest(2); - EXPECT_THROW(ByteArrayUtil::copyBytes(0, dest, 1, 2), ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::copyBytes(0, dest, 1, 2), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, copyBytes_whenNbBytesIs0_shouldDoNothing) @@ -344,38 +434,55 @@ TEST(ByteArrayUtilTest, copyBytes_whenSrcIsInteger_shouldBeSuccess) TEST(ByteArrayUtilTest, copyBytes_whenSrcIsLong_shouldBeSuccess) { uint64_t src = 0x1122334455667788L; - std::vector dest = {0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8}; + std::vector dest + = {0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8}; ByteArrayUtil::copyBytes(src, dest, 0, 1); - ASSERT_EQ(dest, std::vector({0x88, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8})); + ASSERT_EQ( + dest, + std::vector({0x88, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8})); ByteArrayUtil::copyBytes(src, dest, 0, 2); - ASSERT_EQ(dest, std::vector({0x77, 0x88, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8})); + ASSERT_EQ( + dest, + std::vector({0x77, 0x88, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8})); ByteArrayUtil::copyBytes(src, dest, 0, 3); - ASSERT_EQ(dest, std::vector({0x66, 0x77, 0x88, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8})); + ASSERT_EQ( + dest, + std::vector({0x66, 0x77, 0x88, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8})); ByteArrayUtil::copyBytes(src, dest, 0, 4); - ASSERT_EQ(dest, std::vector({0x55, 0x66, 0x77, 0x88, 0xF5, 0xF6, 0xF7, 0xF8})); + ASSERT_EQ( + dest, + std::vector({0x55, 0x66, 0x77, 0x88, 0xF5, 0xF6, 0xF7, 0xF8})); ByteArrayUtil::copyBytes(src, dest, 0, 5); - ASSERT_EQ(dest, std::vector({0x44, 0x55, 0x66, 0x77, 0x88, 0xF6, 0xF7, 0xF8})); + ASSERT_EQ( + dest, + std::vector({0x44, 0x55, 0x66, 0x77, 0x88, 0xF6, 0xF7, 0xF8})); ByteArrayUtil::copyBytes(src, dest, 0, 6); - ASSERT_EQ(dest, std::vector({0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xF7, 0xF8})); + ASSERT_EQ( + dest, + std::vector({0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xF7, 0xF8})); ByteArrayUtil::copyBytes(src, dest, 0, 7); - ASSERT_EQ(dest, std::vector({0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xF8})); + ASSERT_EQ( + dest, + std::vector({0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xF8})); ByteArrayUtil::copyBytes(src, dest, 0, 8); - ASSERT_EQ(dest, std::vector({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88})); + ASSERT_EQ( + dest, + std::vector({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88})); } TEST(ByteArrayUtilTest, isValidHexString_valid) @@ -397,7 +504,8 @@ TEST(ByteArrayUtilTest, fromHex_empty) TEST(ByteArrayUtilTest, fromHex_odd_length) { - EXPECT_THROW(ByteArrayUtil::fromHex(HEXSTRING_ODD), IllegalArgumentException); + EXPECT_THROW( + ByteArrayUtil::fromHex(HEXSTRING_ODD), IllegalArgumentException); } TEST(ByteArrayUtilTest, fromHex_bad_hex) @@ -419,7 +527,6 @@ TEST(ByteArrayUtilTest, fromHex_good_hex) ASSERT_EQ(bytes, BYTEARRAY_LEN_16); } - TEST(ByteArrayUtilTest, toHex_empty) { const std::vector bytes = std::vector(0); @@ -437,20 +544,23 @@ TEST(ByteArrayUtilTest, toHex_bytearray_good) TEST(ByteArrayUtilTest, twoBytesToInt_negative_offset) { - EXPECT_THROW(ByteArrayUtil::twoBytesToInt(BYTEARRAY_LEN_16, -1), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::twoBytesToInt(BYTEARRAY_LEN_16, -1), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, twoBytesToInt_too_short_buffer_1) { - EXPECT_THROW(ByteArrayUtil::twoBytesToInt(BYTEARRAY_LEN_1, 0), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::twoBytesToInt(BYTEARRAY_LEN_1, 0), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, twoBytesToInt_too_short_buffer_2) { - EXPECT_THROW(ByteArrayUtil::twoBytesToInt(BYTEARRAY_LEN_3, 2), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::twoBytesToInt(BYTEARRAY_LEN_3, 2), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, twoBytesToInt_buffer_ok_1) @@ -505,20 +615,23 @@ TEST(ByteArrayUtilTest, twoBytesSignedToInt_buffer_ok_2) TEST(ByteArrayUtilTest, threeBytesToInt_negative_offset) { - EXPECT_THROW(ByteArrayUtil::threeBytesToInt(BYTEARRAY_LEN_16, -1), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::threeBytesToInt(BYTEARRAY_LEN_16, -1), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, threeBytesToInt_too_short_buffer_1) { - EXPECT_THROW(ByteArrayUtil::threeBytesToInt(BYTEARRAY_LEN_2, 0), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::threeBytesToInt(BYTEARRAY_LEN_2, 0), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, threeBytesToInt_too_short_buffer_2) { - EXPECT_THROW(ByteArrayUtil::threeBytesToInt(BYTEARRAY_LEN_3, 1), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::threeBytesToInt(BYTEARRAY_LEN_3, 1), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, threeBytesToInt_buffer_ok_1) @@ -573,20 +686,23 @@ TEST(ByteArrayUtilTest, threeBytesSignedToInt_buffer_ok_2) TEST(ByteArrayUtilTest, fourBytesToInt_negative_offset) { - EXPECT_THROW(ByteArrayUtil::fourBytesToInt(BYTEARRAY_LEN_16, -1), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::fourBytesToInt(BYTEARRAY_LEN_16, -1), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, fourBytesToInt_too_short_buffer_1) { - EXPECT_THROW(ByteArrayUtil::fourBytesToInt(BYTEARRAY_LEN_3, 0), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::fourBytesToInt(BYTEARRAY_LEN_3, 0), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, fourBytesToInt_too_short_buffer_2) { - EXPECT_THROW(ByteArrayUtil::fourBytesToInt(BYTEARRAY_LEN_4, 1), - ArrayIndexOutOfBoundsException); + EXPECT_THROW( + ByteArrayUtil::fourBytesToInt(BYTEARRAY_LEN_4, 1), + ArrayIndexOutOfBoundsException); } TEST(ByteArrayUtilTest, fourBytesToInt_buffer_ok_1) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 9b3b9f3..aa307de 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,26 +1,17 @@ -# ************************************************************************************************* -# Copyright (c) 2021 Calypso Networks Association * -# https://www.calypsonet-asso.org/ * -# * -# See the NOTICE file(s) distributed with this work for additional information regarding * -# copyright ownership. * -# * -# This program and the accompanying materials are made available under the terms of the Eclipse * -# Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * -# * -# SPDX-License-Identifier: EPL-2.0 * -# *************************************************************************************************/ +# ***************************************************************************** +# Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * +# * +# This program and the accompanying materials are made available under the * +# terms of the MIT License which is available at * +# https://opensource.org/licenses/MIT. * +# * +# SPDX-License-Identifier: MIT * +# *****************************************************************************/ SET(EXECUTABLE_NAME keypleutilcpplib_ut) -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKEYPLEUTIL_EXPORT") - INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../main - ${CMAKE_CURRENT_SOURCE_DIR}/../main/bertlv - ${CMAKE_CURRENT_SOURCE_DIR}/../main/cpp - ${CMAKE_CURRENT_SOURCE_DIR}/../main/cpp/exception ) ADD_EXECUTABLE( @@ -30,11 +21,18 @@ ADD_EXECUTABLE( ${CMAKE_CURRENT_SOURCE_DIR}/BerTlvUtilTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ByteArrayUtilTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/HexUtilTest.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/LoggerTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/MainTest.cpp ) # Add Google Test -SET(GOOGLETEST_DIRECTORY ${CMAKE_BINARY_DIR}/bin) INCLUDE(CMakeLists.txt.googletest) -TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME} gtest gmock keypleutilcpplib) +TARGET_LINK_LIBRARIES( + + ${EXECUTABLE_NAME} + + gtest + gmock + Keyple::Util +) diff --git a/src/test/CMakeLists.txt.googletest b/src/test/CMakeLists.txt.googletest index 3b56093..9b3778a 100644 --- a/src/test/CMakeLists.txt.googletest +++ b/src/test/CMakeLists.txt.googletest @@ -1,35 +1,35 @@ -CONFIGURE_FILE(CMakeLists.txt.in ${GOOGLETEST_DIRECTORY}/googletest-download/CMakeLists.txt) -EXECUTE_PROCESS( - COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . - RESULT_VARIABLE result - WORKING_DIRECTORY ${GOOGLETEST_DIRECTORY}/googletest-download -) +# ***************************************************************************** +# Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * +# * +# This program and the accompanying materials are made available under the * +# terms of the MIT License which is available at * +# https://opensource.org/licenses/MIT. * +# * +# SPDX-License-Identifier: MIT * +# *****************************************************************************/ -# Prevent overriding the parent project's compiler/linker -# settings on Windows -set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +# FetchContent added in CMake 3.11, downloads during the configure step +# FetchContent_MakeAvailable was added in CMake 3.14; simpler usage +INCLUDE(FetchContent) -IF(result) - MESSAGE(FATAL_ERROR "CMake step for googletest failed: ${result}") -ENDIF() +IF(NOT EXISTS "${CMAKE_BINARY_DIR}/_deps/googletest-src") -EXECUTE_PROCESS( - COMMAND ${CMAKE_COMMAND} --build . - RESULT_VARIABLE result - WORKING_DIRECTORY ${GOOGLETEST_DIRECTORY}/googletest-download -) + MESSAGE("-- > Fetching GTest from keyple util") + + FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG v1.14.0 + ) +ELSE() + FetchContent_Declare( + googletest + SOURCE_DIR ${CMAKE_BINARY_DIR}/_deps/googletest-src + ) -IF(result) - MESSAGE(FATAL_ERROR "Build step for googletest failed: ${result}") ENDIF() -# Prevent overriding the parent project's compiler/linker -# settings on Windows -#SET(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -# Add googletest directly to our build. This defines -# the gtest and gtest_main targets. -ADD_SUBDIRECTORY(${GOOGLETEST_DIRECTORY}/googletest-src - ${GOOGLETEST_DIRECTORY}/googletest-build - EXCLUDE_FROM_ALL -) \ No newline at end of file +FetchContent_MakeAvailable(googletest) diff --git a/src/test/CMakeLists.txt.in b/src/test/CMakeLists.txt.in deleted file mode 100644 index 5f1bbe5..0000000 --- a/src/test/CMakeLists.txt.in +++ /dev/null @@ -1,28 +0,0 @@ -# ************************************************************************************************* -# Copyright (c) 2021 Calypso Networks Association * -# https://www.calypsonet-asso.org/ * -# * -# See the NOTICE file(s) distributed with this work for additional information regarding * -# copyright ownership. * -# * -# This program and the accompanying materials are made available under the terms of the Eclipse * -# Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * -# * -# SPDX-License-Identifier: EPL-2.0 * -# *************************************************************************************************/ - -cmake_minimum_required(VERSION 2.8.2) - -project(googletest-download NONE) - -include(ExternalProject) -ExternalProject_Add(googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.11.0 - SOURCE_DIR "${GOOGLETEST_DIRECTORY}/googletest-src" - BINARY_DIR "${GOOGLETEST_DIRECTORY}/googletest-build" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" -) diff --git a/src/test/HexUtilTest.cpp b/src/test/HexUtilTest.cpp index e9c75f4..4cdf811 100644 --- a/src/test/HexUtilTest.cpp +++ b/src/test/HexUtilTest.cpp @@ -1,30 +1,26 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association * - * https://www.calypsonet-asso.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "HexUtil.h" +#include "keyple/core/util/HexUtil.hpp" +#include "keyple/core/util/cpp/Arrays.hpp" +#include "keyple/core/util/cpp/exception/StringIndexOutOfBoundsException.hpp" -/* Keyple Core Util */ -#include "Arrays.h" -#include "StringIndexOutOfBoundsException.h" - -using namespace testing; - -using namespace keyple::core::util; -using namespace keyple::core::util::cpp; -using namespace keyple::core::util::cpp::exception; +using keyple::core::util::HexUtil; +using keyple::core::util::cpp::Arrays; +using keyple::core::util::cpp::exception::StringIndexOutOfBoundsException; TEST(HexUtilTest, isValid_whenHexIsValid_shouldReturnTrue) { @@ -58,8 +54,9 @@ TEST(HexUtilTest, toByteArray_whenHexIsOddLength_shouldThrowSIOOBE) TEST(HexUtilTest, toByteArray_whenHexIsValid_shouldBeSuccessful) { - ASSERT_TRUE(Arrays::equals(HexUtil::toByteArray("ABCDEFabcdef"), - {0xAB, 0xCD, 0xEF, 0xAB, 0xCD, 0xEF})); + ASSERT_TRUE(Arrays::equals( + HexUtil::toByteArray("ABCDEFabcdef"), + {0xAB, 0xCD, 0xEF, 0xAB, 0xCD, 0xEF})); } TEST(HexUtilTest, toByte_whenHexIsEmpty_shouldReturn0) @@ -178,8 +175,14 @@ TEST(HexUtilTest, toHex_long) ASSERT_EQ(HexUtil::toHex(static_cast(0xFE34L)), "FE34"); ASSERT_EQ(HexUtil::toHex(static_cast(0xFE3456L)), "FE3456"); ASSERT_EQ(HexUtil::toHex(static_cast(0xFE345678L)), "FE345678"); - ASSERT_EQ(HexUtil::toHex(static_cast(0xFE3456789AL)), "FE3456789A"); - ASSERT_EQ(HexUtil::toHex(static_cast(0xFE3456789ABCL)), "FE3456789ABC"); - ASSERT_EQ(HexUtil::toHex(static_cast(0xFE3456789ABCDEL)), "FE3456789ABCDE"); - ASSERT_EQ(HexUtil::toHex(static_cast(0xFE3456789ABCDEF0L)), "FE3456789ABCDEF0"); + ASSERT_EQ( + HexUtil::toHex(static_cast(0xFE3456789AL)), "FE3456789A"); + ASSERT_EQ( + HexUtil::toHex(static_cast(0xFE3456789ABCL)), "FE3456789ABC"); + ASSERT_EQ( + HexUtil::toHex(static_cast(0xFE3456789ABCDEL)), + "FE3456789ABCDE"); + ASSERT_EQ( + HexUtil::toHex(static_cast(0xFE3456789ABCDEF0L)), + "FE3456789ABCDEF0"); } diff --git a/src/test/LoggerTest.cpp b/src/test/LoggerTest.cpp new file mode 100644 index 0000000..1f35adf --- /dev/null +++ b/src/test/LoggerTest.cpp @@ -0,0 +1,41 @@ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ + +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include "keyple/core/util/HexUtil.hpp" +#include "keyple/core/util/cpp/KeypleStd.hpp" +#include "keyple/core/util/cpp/Logger.hpp" +#include "keyple/core/util/cpp/LoggerFactory.hpp" + +using keyple::core::util::HexUtil; +using keyple::core::util::cpp::Logger; +using keyple::core::util::cpp::LoggerFactory; + +class LoggerTest { }; + +TEST(LoggerTest, debug) +{ + auto logger(LoggerFactory::getLogger(typeid(LoggerTest))); + + logger->debug("This is a int: %\n", static_cast(27)); + logger->debug("This is a uint8_t: %\n", static_cast(27)); + logger->debug("This is a C++ string: %\n", std::string("C++ style string")); + std::vector vec = {0x01, 0x02, 0xFF, 0x04}; + logger->debug("This is a vector: %\n", vec); +} diff --git a/src/test/MainTest.cpp b/src/test/MainTest.cpp index 008dbcc..3a853de 100644 --- a/src/test/MainTest.cpp +++ b/src/test/MainTest.cpp @@ -1,26 +1,24 @@ -/************************************************************************************************** - * Copyright (c) 2021 Calypso Networks Association * - * https://www.calypsonet-asso.org/ * - * * - * See the NOTICE file(s) distributed with this work for additional information regarding * - * copyright ownership. * - * * - * This program and the accompanying materials are made available under the terms of the Eclipse * - * Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0 * - * * - * SPDX-License-Identifier: EPL-2.0 * - **************************************************************************************************/ +/****************************************************************************** + * Copyright (c) 2025 Calypso Networks Association https://calypsonet.org/ * + * * + * See the NOTICE file(s) distributed with this work for additional * + * information regarding copyright ownership. * + * * + * This program and the accompanying materials are made available under the * + * terms of the Eclipse Public License 2.0 which is available at * + * http://www.eclipse.org/legal/epl-2.0 * + * * + * SPDX-License-Identifier: EPL-2.0 * + ******************************************************************************/ #include "gtest/gtest.h" -/* Util */ -#include "Logger.h" +#include "keyple/core/util/cpp/Logger.hpp" -using namespace testing; +using keyple::core::util::cpp::Logger; -using namespace keyple::core::util::cpp; - -int main(int argc, char **argv) +int +main(int argc, char** argv) { /* Initialize GTest */ ::testing::InitGoogleTest(&argc, argv); @@ -29,4 +27,4 @@ int main(int argc, char **argv) /* Run */ return RUN_ALL_TESTS(); -} \ No newline at end of file +} diff --git a/toolchain/arm-unknown-gnueabi-linux.cmake b/toolchain/arm-unknown-gnueabi-linux.cmake index c7c68bc..3683870 100644 --- a/toolchain/arm-unknown-gnueabi-linux.cmake +++ b/toolchain/arm-unknown-gnueabi-linux.cmake @@ -9,10 +9,10 @@ SET(ARM_SYSROOT_DIR ${ARM_TOOLCHAIN_DIR}/arm-unknown-linux-gnueabi/sysroot) # Which C and C++ compiler to use SET(CMAKE_C_COMPILER ${ARM_COMPILER_DIR}/arm-unknown-linux-gnueabi-gcc) -SET(CMAKE_CXX_COMPILER ${ARM_COMPILER_DIR}/arm-unknown-linux-gnueabi-g++) +SET(CMAKE_CXX_COMPILER ${ARM_COMPILER_DIR}/arm-unknown-linux-gnueabi-g++) # Here is the target environment located -SET(CMAKE_FIND_ROOT_PATH ${ARM_SYSROOT_DIR}) +SET(CMAKE_FIND_ROOT_PATH ${ARM_SYSROOT_DIR}) # Adjust the default behaviour of the FIND_XXX() commands: # search headers and libraries in the target environment, @@ -24,4 +24,3 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) # Linker SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} --sysroot=${ARM_SYSROOT_DIR}") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS} --sysroot=${ARM_SYSROOT_DIR} -L${ARM_SYSROOT_DIR}") - diff --git a/toolchain/clang-8-linux.cmake b/toolchain/clang-8-linux.cmake index 1a932d1..93222ef 100644 --- a/toolchain/clang-8-linux.cmake +++ b/toolchain/clang-8-linux.cmake @@ -42,4 +42,3 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # Libraries type SET(LIBRARY_TYPE SHARED) - diff --git a/toolchain/clang-9-linux.cmake b/toolchain/clang-9-linux.cmake index ac30418..4c13b7f 100644 --- a/toolchain/clang-9-linux.cmake +++ b/toolchain/clang-9-linux.cmake @@ -42,4 +42,3 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # Libraries type SET(LIBRARY_TYPE SHARED) - diff --git a/toolchain/clang-linux.cmake b/toolchain/clang-linux.cmake index dde3a80..a69796b 100644 --- a/toolchain/clang-linux.cmake +++ b/toolchain/clang-linux.cmake @@ -42,4 +42,3 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # Libraries type SET(LIBRARY_TYPE SHARED) - diff --git a/toolchain/clang-macos.cmake b/toolchain/clang-macos.cmake index f965786..29a03d5 100644 --- a/toolchain/clang-macos.cmake +++ b/toolchain/clang-macos.cmake @@ -42,4 +42,3 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # Libraries type SET(LIBRARY_TYPE SHARED) - diff --git a/toolchain/clang-windows.cmake b/toolchain/clang-windows.cmake index 606fe65..85be998 100644 --- a/toolchain/clang-windows.cmake +++ b/toolchain/clang-windows.cmake @@ -45,8 +45,8 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MDd") # debug multi thread dll SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GS") # buffers security check SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:precise") # floating point SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:wchar_t") # standard behaviour -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:forScope") # -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:inline") # +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:forScope") # +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:inline") # SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR") # enables RTTI SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Gd") # uses __cdecl convention SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /TP") # all sources are C++ @@ -67,4 +67,3 @@ SET(LIBRARY_TYPE SHARED) # Special tricks INCLUDE(GenerateExportHeader) - diff --git a/toolchain/gcc-10-linux.cmake b/toolchain/gcc-10-linux.cmake index 3fbe78b..3282cd6 100644 --- a/toolchain/gcc-10-linux.cmake +++ b/toolchain/gcc-10-linux.cmake @@ -43,4 +43,3 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmax-errors=10") # Libraries type SET(LIBRARY_TYPE SHARED) - diff --git a/toolchain/gcc-4.8.3-linux.cmake b/toolchain/gcc-4.8.3-linux.cmake index f6af177..e6d3df0 100644 --- a/toolchain/gcc-4.8.3-linux.cmake +++ b/toolchain/gcc-4.8.3-linux.cmake @@ -27,4 +27,3 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) # Linker #SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} --sysroot=${GCC_SYSROOT_DIR}") #SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS} --sysroot=${GCC_SYSROOT_DIR} -L${GCC_SYSROOT_DIR}") - diff --git a/toolchain/gcc-8-linux.cmake b/toolchain/gcc-8-linux.cmake index 6272eb1..db27a7b 100644 --- a/toolchain/gcc-8-linux.cmake +++ b/toolchain/gcc-8-linux.cmake @@ -43,4 +43,3 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmax-errors=10") # Libraries type SET(LIBRARY_TYPE SHARED) - diff --git a/toolchain/gcc-9-linux.cmake b/toolchain/gcc-9-linux.cmake index 21685b2..a6e923d 100644 --- a/toolchain/gcc-9-linux.cmake +++ b/toolchain/gcc-9-linux.cmake @@ -43,4 +43,3 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmax-errors=10") # Libraries type SET(LIBRARY_TYPE SHARED) - diff --git a/toolchain/gcc-linux.cmake b/toolchain/gcc-linux.cmake index a62432d..ff67b6e 100644 --- a/toolchain/gcc-linux.cmake +++ b/toolchain/gcc-linux.cmake @@ -43,4 +43,3 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmax-errors=10") # Libraries type SET(LIBRARY_TYPE SHARED) - diff --git a/toolchain/ios-macos.cmake b/toolchain/ios-macos.cmake index 990470f..3407d82 100644 --- a/toolchain/ios-macos.cmake +++ b/toolchain/ios-macos.cmake @@ -92,4 +92,3 @@ SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-search_paths_first") # Libraries type SET(LIBRARY_TYPE STATIC) -