From 62e2391a149a131462a752ba98b5bdc0c58b3ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=AE=E7=94=9F=E8=8B=A5=E6=A2=A6?= <1070753498@qq.com> Date: Thu, 21 Mar 2024 18:40:32 +0800 Subject: [PATCH] =?UTF-8?q?memcpy=20=E5=AE=9E=E7=8E=B0=EF=BC=9B=20ByteOrde?= =?UTF-8?q?r=20=E5=88=A4=E6=96=AD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .clang-tidy | 57 +------- .github/workflows/build.yml | 47 +++--- .github/workflows/clean_cache.yml | 40 +++++ .github/workflows/delete_workflow.yml | 65 +++++++++ .github/workflows/readme.yml | 4 +- .github/workflows/toolchain.yml | 65 +++++++++ BinaryTree/binarytree.hpp | 203 +++++++++++++------------- ByteOrder/CMakeLists.txt | 1 + ByteOrder/byteorder.cc | 17 +++ CMakeLists.txt | 2 + LinkedList/linkedlist.hpp | 34 ++--- LinkedList/linkedlist_unittest.cc | 4 +- Memcpy/CMakeLists.txt | 4 + Memcpy/memcpy.hpp | 33 +++++ Memcpy/memcpy_unittest.cc | 52 +++++++ Mutex/main.cc | 6 +- OpenSSL/openssl_aes.cc | 9 +- OpenSSL/openssl_rsa.cc | 21 +-- OpenSSL/openssl_utils.hpp | 10 +- README.md | 84 +++++------ 20 files changed, 504 insertions(+), 254 deletions(-) create mode 100644 .github/workflows/clean_cache.yml create mode 100644 .github/workflows/delete_workflow.yml create mode 100644 .github/workflows/toolchain.yml create mode 100644 ByteOrder/CMakeLists.txt create mode 100644 ByteOrder/byteorder.cc create mode 100644 Memcpy/CMakeLists.txt create mode 100644 Memcpy/memcpy.hpp create mode 100644 Memcpy/memcpy_unittest.cc diff --git a/.clang-tidy b/.clang-tidy index f95ff5f..d3a3536 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,60 +1,7 @@ --- -Checks: '-*,clang-analyzer-*,readability-*,performance-*,modernize-*,bugprone-*,cert-,cppcoreguidelines-,portability-*,llvm-*,google-*' +Checks: 'clang-analyzer-*,readability-*,performance-*,modernize-*,bugprone-*,cert-*,portability-*,llvm-*,google-*' WarningsAsErrors: '' HeaderFilterRegex: '.' AnalyzeTemporaryDtors: false -FormatStyle: file +FormatStyle: none User: user -CheckOptions: - - key: readability-identifier-naming.AbstractClassCase - value: CamelCase - - key: readability-identifier-naming.ClassCase - value: CamelCase - - key: readability-identifier-naming.ClassConstantCase - value: UPPER_CASE - - key: readability-identifier-naming.ClassConstantPrefix - value: 'k' - - key: readability-identifier-naming.ClassMemberCase - value: lower_case - - key: readability-identifier-naming.ClassMemberPrefix - value: 'm_' - - key: readability-identifier-naming.ClassMethodCase - value: camelBack - - key: readability-identifier-naming.ConstexprVariableCase - value: UPPER_CASE - - key: readability-identifier-naming.ConstexprVariablePrefix - value: 'k' - - key: readability-identifier-naming.EnumCase - value: CamelCase - - key: readability-identifier-naming.EnumConstantCase - value: UPPER_CASE - - key: readability-identifier-naming.EnumConstantPrefix - value: '' - - key: readability-identifier-naming.FunctionCase - value: camelBack - - key: readability-identifier-naming.FunctionParameterCase - value: lower_case - - key: readability-identifier-naming.GlobalConstantCase - value: UPPER_CASE - - key: readability-identifier-naming.GlobalConstantPrefix - value: 'k' - - key: readability-identifier-naming.GlobalFunctionCase - value: camelBack - - key: readability-identifier-naming.GlobalVariableCase - value: lower_case - - key: readability-identifier-naming.GlobalVariablePrefix - value: 'g_' - - key: readability-identifier-naming.InlineNamespaceCase - value: lower_case - - key: readability-identifier-naming.LocalConstantCase - value: UPPER_CASE - - key: readability-identifier-naming.LocalConstantPrefix - value: 'k' - - key: readability-identifier-naming.LocalVariableCase - value: lower_case - - key: readability-identifier-naming.MacroDefinitionCase - value: UPPER_CASE - - key: readability-identifier-naming.NamespaceCase - value: lower_case - - key: bugprone-narrowing-conversions.IgnoreFloatingPointPrecisionLoss - value: 'false' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 536c3a2..f519d69 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,13 +4,21 @@ on: # push代码时触发workflow push: paths-ignore: # 下列文件的变更不触发部署,可以自行添加 - - '.clang-format' + - '.github/workflows/clean_cache.yml' + - '.github/workflows/delete_workflow.yml' + - '.github/workflows/readme.yml' + - '.github/workflows/toolchain.yml' + - '.clang*' - '.gitignore' - 'LICENSE' - 'README*' pull_request: paths-ignore: # 下列文件的变更不触发部署,可以自行添加 - - '.clang-format' + - '.github/workflows/clean_cache.yml' + - '.github/workflows/delete_workflow.yml' + - '.github/workflows/readme.yml' + - '.github/workflows/toolchain.yml' + - '.clang*' - '.gitignore' - 'LICENSE' - 'README*' @@ -30,25 +38,30 @@ jobs: - "Release" generators: - "Ninja" + vcpkg_libs: + - glog breakpad benchmark gtest openssl[tools] curl[openssl,brotli,c-ares,http2,tool] + + steps: + - name: Restore windows vcpkg + if: startsWith(matrix.os, 'windows') + uses: actions/cache/restore@v3 + with: + path: C:\vcpkg\installed + key: ${{ runner.os }}-vcpkg-installed-${{ matrix.os }} + - name: Restore macos or ubuntu vcpkg + if: startsWith(matrix.os, 'macos') || startsWith(matrix.os, 'ubuntu') + uses: actions/cache/restore@v3 + with: + path: /usr/local/share/vcpkg/installed + key: ${{ runner.os }}-vcpkg-installed-${{ matrix.os }} - steps: - - name: cache vcpkg - uses: actions/cache@v3 - with: - path: | - C:\vcpkg\installed - /usr/local/share/vcpkg/installed - key: ${{ runner.os }}-vcpkg-installed-${{ matrix.os }}-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-vcpkg-installed-${{ matrix.os }}- - ${{ runner.os }}-vcpkg-installed- - name: Install dependencies on windows if: startsWith(matrix.os, 'windows') run: | choco install ninja ninja --version cmake --version - vcpkg install glog breakpad benchmark gtest openssl[tools] curl[openssl,brotli,c-ares,http2,tool] --triplet x64-windows + vcpkg install ${{ matrix.vcpkg_libs }} --triplet x64-windows - name: Install dependencies on macos if: startsWith(matrix.os, 'macos') shell: bash @@ -57,7 +70,7 @@ jobs: ninja --version cmake --version clang --version - vcpkg install glog breakpad benchmark gtest openssl[tools] curl[openssl,brotli,c-ares,http2,tool] --triplet x64-osx + vcpkg install ${{ matrix.vcpkg_libs }} --triplet x64-osx - name: Install dependencies on ubuntu if: startsWith(matrix.os, 'ubuntu') run: | @@ -66,9 +79,9 @@ jobs: ninja --version cmake --version gcc --version - vcpkg install glog breakpad benchmark gtest openssl[tools] curl[openssl,brotli,c-ares,http2,tool] --triplet x64-linux + vcpkg install ${{ matrix.vcpkg_libs }} --triplet x64-linux - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 1 diff --git a/.github/workflows/clean_cache.yml b/.github/workflows/clean_cache.yml new file mode 100644 index 0000000..2db7538 --- /dev/null +++ b/.github/workflows/clean_cache.yml @@ -0,0 +1,40 @@ +name: Cleanup caches by a branch +on: + # 每周一 0 点触发 + schedule: + - cron: '0 0 * * 1' + workflow_dispatch: + +jobs: + cleanup: + runs-on: ubuntu-latest + permissions: + # `actions:write` permission is required to delete caches + # See also: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-a-github-actions-cache-for-a-repository-using-a-cache-id + actions: write + contents: read + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Cleanup + run: | + gh extension install actions/gh-actions-cache + + REPO=${{ github.repository }} + BRANCH=${{ github.ref }} + + echo "Fetching list of cache key" + cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH | cut -f 1 ) + + ## Setting this to not fail the workflow while deleting cache keys. + set +e + echo "Deleting caches..." + for cacheKey in $cacheKeysForPR + do + gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm + done + echo "Done" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + \ No newline at end of file diff --git a/.github/workflows/delete_workflow.yml b/.github/workflows/delete_workflow.yml new file mode 100644 index 0000000..ae96aae --- /dev/null +++ b/.github/workflows/delete_workflow.yml @@ -0,0 +1,65 @@ +name: Delete old workflow runs +on: + workflow_dispatch: + inputs: + days: + description: 'Days-worth of runs to keep for each workflow' + required: true + default: '30' + minimum_runs: + description: 'Minimum runs to keep for each workflow' + required: true + default: '6' + delete_workflow_pattern: + description: 'Name or filename of the workflow (if not set, all workflows are targeted)' + required: false + delete_workflow_by_state_pattern: + description: 'Filter workflows by state: active, deleted, disabled_fork, disabled_inactivity, disabled_manually' + required: true + default: "ALL" + type: choice + options: + - "ALL" + - active + - deleted + - disabled_inactivity + - disabled_manually + delete_run_by_conclusion_pattern: + description: 'Remove runs based on conclusion: action_required, cancelled, failure, skipped, success' + required: true + default: "failure" + type: choice + options: + - "ALL" + - "Unsuccessful: action_required,cancelled,failure,skipped" + - action_required + - cancelled + - failure + - skipped + - success + dry_run: + description: 'Logs simulated changes, no deletions are performed' + required: false + +jobs: + del_runs: + runs-on: ubuntu-latest + permissions: + actions: write + steps: + - name: Delete workflow runs + uses: Mattraks/delete-workflow-runs@v2 + with: + token: ${{ github.token }} + repository: ${{ github.repository }} + retain_days: ${{ github.event.inputs.days }} + keep_minimum_runs: ${{ github.event.inputs.minimum_runs }} + delete_workflow_pattern: ${{ github.event.inputs.delete_workflow_pattern }} + delete_workflow_by_state_pattern: ${{ github.event.inputs.delete_workflow_by_state_pattern }} + delete_run_by_conclusion_pattern: >- + ${{ + startsWith(github.event.inputs.delete_run_by_conclusion_pattern, 'Unsuccessful:') + && 'action_required,cancelled,failure,skipped' + || github.event.inputs.delete_run_by_conclusion_pattern + }} + dry_run: ${{ github.event.inputs.dry_run }} diff --git a/.github/workflows/readme.yml b/.github/workflows/readme.yml index 0cf4fb1..aff09d7 100644 --- a/.github/workflows/readme.yml +++ b/.github/workflows/readme.yml @@ -12,9 +12,9 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Setup Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: 12.x # ISO Langusge Codes: https://cloud.google.com/translate/docs/languages diff --git a/.github/workflows/toolchain.yml b/.github/workflows/toolchain.yml new file mode 100644 index 0000000..a53ce43 --- /dev/null +++ b/.github/workflows/toolchain.yml @@ -0,0 +1,65 @@ +name: Build toolchain + +on: + # 清理 Cache 后触发 + workflow_run: + workflows: [Cleanup caches by a branch] + types: completed + # 手动触发 + workflow_dispatch: + +jobs: + build: + name: Build + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + - windows-latest + - macos-latest + - ubuntu-latest + vcpkg_libs: + - glog breakpad benchmark gtest openssl[tools] curl[openssl,brotli,c-ares,http2,tool] + + steps: + - name: Install dependencies on windows + if: startsWith(matrix.os, 'windows') + shell: bash + run: | + choco install ninja + ninja --version + cmake --version + vcpkg install ${{ matrix.vcpkg_libs }} --triplet x64-windows + - name: Install dependencies on macos + if: startsWith(matrix.os, 'macos') + shell: bash + run: | + brew install ninja nasm pkg-config + ninja --version + cmake --version + clang --version + vcpkg install ${{ matrix.vcpkg_libs }} --triplet x64-osx + - name: Install dependencies on ubuntu + if: startsWith(matrix.os, 'ubuntu') + shell: bash + run: | + sudo apt-get update + sudo apt-get install ninja-build nasm build-essential libgl1-mesa-dev + ninja --version + cmake --version + gcc --version + vcpkg install breakpad ${{ matrix.vcpkg_libs }} --triplet x64-linux + + - name: cache windows vcpkg + if: startsWith(matrix.os, 'windows') + uses: actions/cache/save@v3 + with: + path: C:\vcpkg\installed + key: ${{ runner.os }}-vcpkg-installed-${{ matrix.os }} + - name: cache macos or ubuntu vcpkg + if: startsWith(matrix.os, 'macos') || startsWith(matrix.os, 'ubuntu') + uses: actions/cache/save@v3 + with: + path: /usr/local/share/vcpkg/installed + key: ${{ runner.os }}-vcpkg-installed-${{ matrix.os }} diff --git a/BinaryTree/binarytree.hpp b/BinaryTree/binarytree.hpp index 7602828..87e96d6 100644 --- a/BinaryTree/binarytree.hpp +++ b/BinaryTree/binarytree.hpp @@ -8,7 +8,7 @@ class BinaryTree { public: BinaryTree() = default; - BinaryTree(const std::vector &data); + explicit BinaryTree(const std::vector &data); BinaryTree(const BinaryTree &other); BinaryTree(BinaryTree &&other) noexcept; auto operator=(const BinaryTree &other) -> BinaryTree &; @@ -39,8 +39,8 @@ class BinaryTree Node *left; Node *right; - Node(const T &data); - Node(T &&data) noexcept; + explicit Node(const T &data); + explicit Node(T &&data) noexcept; }; Node *root = nullptr; @@ -107,37 +107,38 @@ auto BinaryTree::operator==(const BinaryTree &other) const -> bool { if (root == nullptr && other.root == nullptr) { return true; - } else if (root == nullptr || other.root == nullptr) { + } + if (root == nullptr || other.root == nullptr) { return false; - } else { - std::vector::Node *> nodes1; - std::vector::Node *> nodes2; - nodes1.push_back(root); - nodes2.push_back(other.root); - while (!nodes1.empty() && !nodes2.empty()) { - typename BinaryTree::Node *current1 = nodes1.back(); - nodes1.pop_back(); - typename BinaryTree::Node *current2 = nodes2.back(); - nodes2.pop_back(); - if (current1->data != current2->data) { // 比较当前节点的值 - return false; - } - if (current1->left && current2->left) { // 比较左子节点的值 - nodes1.push_back(current1->left); - nodes2.push_back(current2->left); - } else if (current1->left || current2->left) { - // 如果一个有左子节点,一个没有左子节点,就返回false - return false; - } - if (current1->right && current2->right) { // 比较右子节点的值 - nodes1.push_back(current1->right); - nodes2.push_back(current2->right); - } else if (current1->right || current2->right) { - // 如果一个有右子节点,一个没有右子节点,就返回false - return false; - } + } + std::vector::Node *> nodes1; + std::vector::Node *> nodes2; + nodes1.push_back(root); + nodes2.push_back(other.root); + while (!nodes1.empty() && !nodes2.empty()) { + typename BinaryTree::Node *current1 = nodes1.back(); + nodes1.pop_back(); + typename BinaryTree::Node *current2 = nodes2.back(); + nodes2.pop_back(); + if (current1->data != current2->data) { // 比较当前节点的值 + return false; + } + if (current1->left && current2->left) { // 比较左子节点的值 + nodes1.push_back(current1->left); + nodes2.push_back(current2->left); + } else if (current1->left || current2->left) { + // 如果一个有左子节点,一个没有左子节点,就返回false + return false; + } + if (current1->right && current2->right) { // 比较右子节点的值 + nodes1.push_back(current1->right); + nodes2.push_back(current2->right); + } else if (current1->right || current2->right) { + // 如果一个有右子节点,一个没有右子节点,就返回false + return false; } } + return true; } @@ -152,42 +153,45 @@ auto BinaryTree::operator<(const BinaryTree &other) const -> bool { if (root == nullptr && other.root == nullptr) { return false; - } else if (root == nullptr) { + } + if (root == nullptr) { return true; - } else if (other.root == nullptr) { + } + if (other.root == nullptr) { return false; - } else { - std::vector::Node *> nodes1; - std::vector::Node *> nodes2; - nodes1.push_back(root); - nodes2.push_back(other.root); - while (!nodes1.empty() && !nodes2.empty()) { - typename BinaryTree::Node *current1 = nodes1.back(); - nodes1.pop_back(); - typename BinaryTree::Node *current2 = nodes2.back(); - nodes2.pop_back(); - if (current1->data < current2->data) { // 比较当前节点的值 - return true; - } else if (current1->data > current2->data) { // 比较当前节点的值 - return false; - } - if (current1->left && current2->left) { // 比较左子节点的值 - nodes1.push_back(current1->left); - nodes2.push_back(current2->left); - } else if (current1->left || current2->left) { - // 如果一个有左子节点,一个没有左子节点,就返回false - return false; - } - if (current1->right && current2->right) { - // 比较右子节点的值 - nodes1.push_back(current1->right); - nodes2.push_back(current2->right); - } else if (current1->right || current2->right) { - // 如果一个有右子节点,一个没有右子节点,就返回false - return false; - } + } + std::vector::Node *> nodes1; + std::vector::Node *> nodes2; + nodes1.push_back(root); + nodes2.push_back(other.root); + while (!nodes1.empty() && !nodes2.empty()) { + typename BinaryTree::Node *current1 = nodes1.back(); + nodes1.pop_back(); + typename BinaryTree::Node *current2 = nodes2.back(); + nodes2.pop_back(); + if (current1->data < current2->data) { // 比较当前节点的值 + return true; + } + if (current1->data > current2->data) { // 比较当前节点的值 + return false; + } + if (current1->left && current2->left) { // 比较左子节点的值 + nodes1.push_back(current1->left); + nodes2.push_back(current2->left); + } else if (current1->left || current2->left) { + // 如果一个有左子节点,一个没有左子节点,就返回false + return false; + } + if (current1->right && current2->right) { + // 比较右子节点的值 + nodes1.push_back(current1->right); + nodes2.push_back(current2->right); + } else if (current1->right || current2->right) { + // 如果一个有右子节点,一个没有右子节点,就返回false + return false; } } + return false; } @@ -196,41 +200,44 @@ auto BinaryTree::operator>(const BinaryTree &other) const -> bool { if (root == nullptr && other.root == nullptr) { return false; - } else if (root == nullptr) { + } + if (root == nullptr) { return false; - } else if (other.root == nullptr) { + } + if (other.root == nullptr) { return true; - } else { - std::vector::Node *> nodes1; - std::vector::Node *> nodes2; - nodes1.push_back(root); - nodes2.push_back(other.root); - while (!nodes1.empty() && !nodes2.empty()) { - typename BinaryTree::Node *current1 = nodes1.back(); - nodes1.pop_back(); - typename BinaryTree::Node *current2 = nodes2.back(); - nodes2.pop_back(); - if (current1->data > current2->data) { // 比较当前节点的值 - return true; - } else if (current1->data < current2->data) { // 比较当前节点的值 - return false; - } - if (current1->left && current2->left) { // 比较左子节点的值 - nodes1.push_back(current1->left); - nodes2.push_back(current2->left); - } else if (current1->left || current2->left) { - // 如果一个有左子节点,一个没有左子节点,就返回false - return false; - } - if (current1->right && current2->right) { // 比较右子节点的值 - nodes1.push_back(current1->right); - nodes2.push_back(current2->right); - } else if (current1->right || current2->right) { - // 如果一个有右子节点,一个没有右子节点,就返回false - return false; - } + } + std::vector::Node *> nodes1; + std::vector::Node *> nodes2; + nodes1.push_back(root); + nodes2.push_back(other.root); + while (!nodes1.empty() && !nodes2.empty()) { + typename BinaryTree::Node *current1 = nodes1.back(); + nodes1.pop_back(); + typename BinaryTree::Node *current2 = nodes2.back(); + nodes2.pop_back(); + if (current1->data > current2->data) { // 比较当前节点的值 + return true; + } + if (current1->data < current2->data) { // 比较当前节点的值 + return false; + } + if (current1->left && current2->left) { // 比较左子节点的值 + nodes1.push_back(current1->left); + nodes2.push_back(current2->left); + } else if (current1->left || current2->left) { + // 如果一个有左子节点,一个没有左子节点,就返回false + return false; + } + if (current1->right && current2->right) { // 比较右子节点的值 + nodes1.push_back(current1->right); + nodes2.push_back(current2->right); + } else if (current1->right || current2->right) { + // 如果一个有右子节点,一个没有右子节点,就返回false + return false; } } + return false; } @@ -424,7 +431,7 @@ void BinaryTree::preorderTraversal() const stack.push_back(current->left); } } - std::cout << std::endl; + std::cout << '\n'; } template @@ -449,7 +456,7 @@ void BinaryTree::inorderTraversal() const std::cout << current->data << " "; current = current->right; } - std::cout << std::endl; + std::cout << '\n'; } template @@ -480,7 +487,7 @@ void BinaryTree::postorderTraversal() const current = nullptr; } } - std::cout << std::endl; + std::cout << '\n'; } template @@ -503,7 +510,7 @@ void BinaryTree::levelorderTraversal() const queue.push_back(current->right); } } - std::cout << std::endl; + std::cout << '\n'; } template diff --git a/ByteOrder/CMakeLists.txt b/ByteOrder/CMakeLists.txt new file mode 100644 index 0000000..259e090 --- /dev/null +++ b/ByteOrder/CMakeLists.txt @@ -0,0 +1 @@ +add_executable(ByteOrder byteorder.cc) diff --git a/ByteOrder/byteorder.cc b/ByteOrder/byteorder.cc new file mode 100644 index 0000000..d45b45e --- /dev/null +++ b/ByteOrder/byteorder.cc @@ -0,0 +1,17 @@ +#include + +// 大端:高位字节存放在内存的低地址,低位字节存放在内存的高地址 +// 0x12345678, 大端为 0x12 0x34 0x56 0x78, 小端为 0x78 0x56 0x34 0x12 + +auto main() -> int +{ + int i = 1; + char c = *reinterpret_cast(&i); + if (c == 1) { + std::cout << "Little Endian" << '\n'; + } else { + std::cout << "Big Endian" << '\n'; + } + + return 0; +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 87aa43b..7322a3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,11 +101,13 @@ add_subdirectory(Algorithm) add_subdirectory(AtomicQueue) add_subdirectory(BinaryTree) add_subdirectory(Breakpad) +add_subdirectory(ByteOrder) add_subdirectory(CountDownLatch) add_subdirectory(Curl) add_subdirectory(DesignPattern) add_subdirectory(Glog) add_subdirectory(LinkedList) +add_subdirectory(Memcpy) add_subdirectory(MonitorDir) add_subdirectory(Mutex) add_subdirectory(OpenSSL) diff --git a/LinkedList/linkedlist.hpp b/LinkedList/linkedlist.hpp index eea916f..e45779f 100644 --- a/LinkedList/linkedlist.hpp +++ b/LinkedList/linkedlist.hpp @@ -9,11 +9,11 @@ class LinkedList { public: LinkedList() - : head_(nullptr) + : m_head(nullptr) {} ~LinkedList() { - while (head_) { + while (m_head) { pop_front(); } } @@ -21,25 +21,25 @@ class LinkedList void push_front(const T &data) { Node *const new_node = new Node(data); - new_node->next = head_; - head_ = new_node; + new_node->next = m_head; + m_head = new_node; } void pop_front() { - Node *const old_head = head_; - head_ = head_->next; + Node *const old_head = m_head; + m_head = m_head->next; delete old_head; } - auto front() -> T & { return head_->data; } + auto front() -> T & { return m_head->data; } - auto empty() -> bool { return head_ == nullptr; } + auto empty() -> bool { return m_head == nullptr; } - size_t size() + auto size() -> size_t { size_t size = 0; - Node *node = head_; + Node *node = m_head; while (node) { ++size; node = node->next; @@ -49,31 +49,31 @@ class LinkedList void reverse() { - Node *prev = nullptr; // 前一个节点 - Node *curr = head_; // 当前节点 + Node *prev = nullptr; // 前一个节点 + Node *curr = m_head; // 当前节点 while (curr) { Node *next = curr->next; // 下一个节点 curr->next = prev; // 当前节点指向前一个节点 prev = curr; // 前一个节点指向当前节点 curr = next; // 当前节点指向下一个节点 } - head_ = prev; // 头节点指向前一个节点 + m_head = prev; // 头节点指向前一个节点 } void print() { - Node *node = head_; + Node *node = m_head; while (node) { std::cout << node->data << " "; node = node->next; } - std::cout << std::endl; + std::cout << '\n'; } private: struct Node { - Node(const T &data) + explicit Node(const T &data) : data(data) , next(nullptr) {} @@ -82,5 +82,5 @@ class LinkedList Node *next; }; - Node *head_; + Node *m_head; }; diff --git a/LinkedList/linkedlist_unittest.cc b/LinkedList/linkedlist_unittest.cc index f2611d7..4e52a07 100644 --- a/LinkedList/linkedlist_unittest.cc +++ b/LinkedList/linkedlist_unittest.cc @@ -35,7 +35,7 @@ TEST(LinkedList, front) linked_list.push_front(4); linked_list.push_front(5); linked_list.print(); - std::cout << linked_list.front() << std::endl; + std::cout << linked_list.front() << '\n'; } TEST(LinkedList, empty) @@ -86,7 +86,7 @@ TEST(LinkedList, print) linked_list.print(); } -int main(int argc, char *argv[]) +auto main(int argc, char *argv[]) -> int { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/Memcpy/CMakeLists.txt b/Memcpy/CMakeLists.txt new file mode 100644 index 0000000..840a9a6 --- /dev/null +++ b/Memcpy/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable(memcpy_unittest memcpy_unittest.cc memcpy.hpp) +target_link_libraries(memcpy_unittest PRIVATE GTest::gtest GTest::gtest_main + GTest::gmock GTest::gmock_main) +add_test(NAME memcpy_unittest COMMAND memcpy_unittest) diff --git a/Memcpy/memcpy.hpp b/Memcpy/memcpy.hpp new file mode 100644 index 0000000..2da2a89 --- /dev/null +++ b/Memcpy/memcpy.hpp @@ -0,0 +1,33 @@ + +#pragma once + +#include + +void *custom_memcpy(void *dest, const void *src, size_t n) +{ + if (dest == nullptr || src == nullptr) { + return nullptr; + } + + size_t copy_size = std::min(n, sizeof(dest)); + copy_size = std::min(copy_size, sizeof(src)); + if (copy_size == 0) { + return dest; + } + + char *d = static_cast(dest); + const char *s = static_cast(src); + + if (d <= s) { + // No overlap, copy from start to end + for (size_t i = 0; i < copy_size; ++i) { + d[i] = s[i]; + } + } else { + // Overlap, copy from end to start + for (size_t i = copy_size; i > 0; --i) { + d[i - 1] = s[i - 1]; + } + } + return dest; +} \ No newline at end of file diff --git a/Memcpy/memcpy_unittest.cc b/Memcpy/memcpy_unittest.cc new file mode 100644 index 0000000..aac9ae8 --- /dev/null +++ b/Memcpy/memcpy_unittest.cc @@ -0,0 +1,52 @@ +#include "memcpy.hpp" + +#include + +#include + +TEST(custom_memcpy, normal_cpy) +{ + const char src[50] = "Hello"; + char dest[50]; + custom_memcpy(dest, src, strlen(src) + 1); + EXPECT_STREQ(dest, "Hello"); +} + +TEST(custom_memcpy, normal_cpy2) +{ + const char src[50] = "www.baidu.com"; + char dest[50]; + custom_memcpy(dest, src + 4, 5); + dest[5] = '\0'; + EXPECT_STREQ(dest, "baidu"); +} + +TEST(custom_memcpy, null_cpy) +{ + const char src[50] = "Hello"; + char *dest = nullptr; + custom_memcpy(dest, src, strlen(src) + 1); + EXPECT_STREQ(dest, nullptr); +} + +TEST(custom_memcpy, zero_cpy) +{ + const char src[50] = "Hello"; + char dest[50] = {0}; + custom_memcpy(dest, src, 0); + EXPECT_STREQ(dest, ""); +} + +TEST(custom_memcpy, overlap_cpy) +{ + const char src[50] = "Hello"; + char dest[50] = "***** World"; + custom_memcpy(dest, src, 5); + EXPECT_STREQ(dest, "Hello World"); +} + +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/Mutex/main.cc b/Mutex/main.cc index d3f89ca..f9689ee 100644 --- a/Mutex/main.cc +++ b/Mutex/main.cc @@ -13,7 +13,7 @@ class TestMutex { while (count < 30) { MutexLocker locker(&m_mutex); - std::cout << std::this_thread::get_id() << ": " << ++count << std::endl; + std::cout << std::this_thread::get_id() << ": " << ++count << '\n'; } } }; @@ -24,8 +24,8 @@ auto main(int argc, char *argv[]) -> int (void) argv; TestMutex test; - std::thread t1(std::bind(&TestMutex::run, &test)); - std::thread t2(std::bind(&TestMutex::run, &test)); + std::thread t1([ObjectPtr = &test] { ObjectPtr->run(); }); + std::thread t2([ObjectPtr = &test] { ObjectPtr->run(); }); t1.join(); t2.join(); diff --git a/OpenSSL/openssl_aes.cc b/OpenSSL/openssl_aes.cc index b56df9f..4bec400 100644 --- a/OpenSSL/openssl_aes.cc +++ b/OpenSSL/openssl_aes.cc @@ -53,7 +53,7 @@ auto aes_encrypt(const std::string &key, const std::string &iv, const std::strin cipher.resize(max_cipher_len); if (EVP_EncryptUpdate(ctx, - reinterpret_cast(&cipher[0]), + reinterpret_cast(cipher.data()), &len, reinterpret_cast(plain.c_str()), plain_len) @@ -65,7 +65,8 @@ auto aes_encrypt(const std::string &key, const std::string &iv, const std::strin int cipher_len = len; - if (EVP_EncryptFinal_ex(ctx, reinterpret_cast(&cipher[0]) + len, &len) != 1) { + if (EVP_EncryptFinal_ex(ctx, reinterpret_cast(cipher.data()) + len, &len) + != 1) { openssl_error(); EVP_CIPHER_CTX_free(ctx); return cipher; @@ -108,7 +109,7 @@ auto aes_decrypt(const std::string &key, const std::string &iv, const std::strin plain.resize(max_plain_len); if (EVP_DecryptUpdate(ctx, - reinterpret_cast(&plain[0]), + reinterpret_cast(plain.data()), &len, reinterpret_cast(cipher.c_str()), cipher_len) @@ -120,7 +121,7 @@ auto aes_decrypt(const std::string &key, const std::string &iv, const std::strin int plain_len = len; - if (EVP_DecryptFinal_ex(ctx, reinterpret_cast(&plain[0]) + len, &len) != 1) { + if (EVP_DecryptFinal_ex(ctx, reinterpret_cast(plain.data()) + len, &len) != 1) { openssl_error(); EVP_CIPHER_CTX_free(ctx); return plain; diff --git a/OpenSSL/openssl_rsa.cc b/OpenSSL/openssl_rsa.cc index 6a30c02..85c4d22 100644 --- a/OpenSSL/openssl_rsa.cc +++ b/OpenSSL/openssl_rsa.cc @@ -54,7 +54,7 @@ void rsa_generate_key(std::string &pub_key, std::string &pri_key) int len = BIO_pending(bio); pub_key.resize(len); - if (BIO_read(bio, &pub_key[0], len) != len) { + if (BIO_read(bio, pub_key.data(), len) != len) { openssl_error(); BIO_free(bio); BN_free(e); @@ -83,7 +83,7 @@ void rsa_generate_key(std::string &pub_key, std::string &pri_key) len = BIO_pending(bio); pri_key.resize(len); - if (BIO_read(bio, &pri_key[0], len) != len) { + if (BIO_read(bio, pri_key.data(), len) != len) { openssl_error(); BIO_free(bio); BN_free(e); @@ -126,7 +126,7 @@ auto rsa_encrypt(const std::string &pub_key, const std::string &plain) -> std::s int len = RSA_public_encrypt(static_cast(plain.size()), reinterpret_cast(plain.c_str()), - reinterpret_cast(&cipher[0]), + reinterpret_cast(cipher.data()), rsa, RSA_PKCS1_PADDING); if (len == -1) { @@ -174,7 +174,7 @@ auto rsa_decrypt(const std::string &pri_key, const std::string &cipher) -> std:: int len = RSA_private_decrypt(static_cast(cipher.size()), reinterpret_cast(cipher.c_str()), - reinterpret_cast(&plain[0]), + reinterpret_cast(plain.data()), rsa, RSA_PKCS1_PADDING); if (len == -1) { @@ -194,15 +194,16 @@ auto rsa_decrypt(const std::string &pri_key, const std::string &cipher) -> std:: TEST(openssl_rsa, rsa_encrypt_decrypt) { - auto plain = "hello world"; - std::string pub_key, pri_key; + const auto *plain = "hello world"; + std::string pub_key; + std::string pri_key; rsa_generate_key(pub_key, pri_key); - std::cout << "rsa pub key: " << pub_key << std::endl; - std::cout << "rsa pri key: " << pri_key << std::endl; + std::cout << "rsa pub key: " << pub_key << '\n'; + std::cout << "rsa pri key: " << pri_key << '\n'; auto cipher = rsa_encrypt(pub_key, plain); - std::cout << "rsa cipher: " << toHex(cipher) << std::endl; + std::cout << "rsa cipher: " << toHex(cipher) << '\n'; auto plain2 = rsa_decrypt(pri_key, cipher); - std::cout << "rsa plain: " << plain2 << std::endl; + std::cout << "rsa plain: " << plain2 << '\n'; EXPECT_EQ(plain, plain2); } diff --git a/OpenSSL/openssl_utils.hpp b/OpenSSL/openssl_utils.hpp index c1f7b23..cc878da 100644 --- a/OpenSSL/openssl_utils.hpp +++ b/OpenSSL/openssl_utils.hpp @@ -13,17 +13,17 @@ // openssl version void openssl_version() { - std::cout << "openssl version: " << OpenSSL_version(OPENSSL_VERSION) << std::endl; - std::cout << "openssl version number: " << OpenSSL_version_num() << std::endl; + std::cout << "openssl version: " << OpenSSL_version(OPENSSL_VERSION) << '\n'; + std::cout << "openssl version number: " << OpenSSL_version_num() << '\n'; } // openssl error void openssl_error() { auto error = ERR_get_error(); - std::cout << "openssl error: " << ERR_error_string(error, nullptr) << std::endl; - std::cout << "openssl error reason: " << ERR_reason_error_string(error) << std::endl; - std::cout << "openssl error library: " << ERR_lib_error_string(error) << std::endl; + std::cout << "openssl error: " << ERR_error_string(error, nullptr) << '\n'; + std::cout << "openssl error reason: " << ERR_reason_error_string(error) << '\n'; + std::cout << "openssl error library: " << ERR_lib_error_string(error) << '\n'; } auto toHex(const std::string &str) -> std::string diff --git a/README.md b/README.md index b40fdb6..318b64c 100644 --- a/README.md +++ b/README.md @@ -5,44 +5,46 @@ ## 一些过时的C/C++代码 -1. [Algorithm](./Algorithm/) - 1. [Search](./Algorithm/Search/search.hpp)---------->各种查找算法的实现,以及单元测试和基于Google Benchmark的性能测试; - 1. [std_search_examples](./Algorithm/Search/std_search_examples.cc)---------->STL中查找算法的例子; - 2. [Sort](./Algorithm/Sort/sort.hpp)---------->各种排序算法的实现,以及单元测试和基于Google Benchmark的性能测试; - 1. [std_sort_examples](./Algorithm/Sort/std_sort_examples.cc)---------->STL中排序算法的例子; -2. [AtomicQueue](./AtomicQueue/atomicqueue.hpp)---------->使用std::atomic实现的线程安全的队列; -3. [BinaryTree](./BinaryTree/binarytree.hpp)---------->二叉树的相关操作,插入、移除、查找、打印; -4. [Client](./Client/client.cpp)---------->一个简单的Linux select socket客户端; -5. [CountDownLatch](./CountDownLatch/countdownlatch.hpp)---------->使用std::mutex和std::condition_variable实现的简单倒计时门闩; -6. [Curl](./Curl/)---------->curl的简单使用; - 1. [TcpClient](./Curl/tcpclient.hpp)---------->使用curl实现的简单TCP客户端; - 2. [HttpClient](./Curl/httpclient.hpp)---------->使用curl实现的简单HTTP同步客户端; - 3. [HttpClientAsync](./Curl/httpclient_async.hpp)---------->使用curl实现的简单HTTP异步客户端; -7. [Breakpad](./Breakpad/breakpad.hpp)---------->Google Breakpad的简单封装; -8. [DesignPattern](./DesignPattern)---------->设计模式的一些例子; - 1. [Factory](./DesignPattern/Factory/factory.hpp)---------->工厂模式; - 2. [MVC](./DesignPattern/MVC/model.hpp)---------->MVC模式; - 3. [Observer](./DesignPattern/Observer/observer.hpp)---------->观察者模式; - 4. [Singleton](./DesignPattern/Singleton/singleton.hpp)---------->单例模式; -9. [Glog](./Glog/main.cc)---------->Google Glog的例子; -10. [Icmp](./Icmp/icmp.hpp)---------->Linux ICMP协议的简单封装; -11. [LinkedList](./LinkedList/linkedlist.hpp)---------->链表的相关操作,插入、移除、反转、打印; -12. [MonitorDir](./MonitorDir/monitordir.hpp)---------->Windows(`ReadDirectoryChangesW`),MacOS(`FSEvents`)和Linux(`inotify`)目录监控的简单例子; -13. [Mutex](./Mutex/mutex.hpp)---------->使用std::atomic_flag实现的简单互斥锁和自旋锁; -14. [OpenSSL](./OpenSSL)---------->OpenSSL的一些例子; - 1. [aes](./OpenSSL/openssl_aes.cc)---------->AES加解密的例子; - 2. [base64](./OpenSSL/openssl_base64.cc)---------->Base64编解码的例子; - 3. [hash](./OpenSSL/openssl_hash.cc)---------->SHA-256的例子; - 4. [hmac](./OpenSSL/openssl_hmac.cc)---------->HMAC的例子; - 5. [pem](./OpenSSL/openssl_pem.cc)---------->PEM格式的例子; - 6. [rsa](./OpenSSL/openssl_rsa.cc)---------->RSA加解密的例子; - 7. [sm4](./OpenSSL/openssl_sm4.cc)---------->SM4加解密的例子; - 8. [x509](./OpenSSL/openssl_x509.cc)---------->X509证书的例子; - 9. [bash](./OpenSSL/openssl_bash.sh)---------->OpenSSL命令行的例子; -15. [Server](./Server)---------->Linux Server的一些例子; -16. [server_epoll](./Server/server_epoll.cc)---------->Epoll的例子; -17. [server_poll](./Server/server_poll.cc)---------->Poll的例子; -18. [server_select](./Server/server_select.cc)---------->Select的例子; -19. [Thread](./Thread/)---------->基于std::thread实现的线程类,包括线程池; - 1. [Thread](./Thread/thread.hpp)---------->线程类; - 2. [ThreadPool](./Thread/threadpool.hpp)---------->线程池; +1. [Algorithm](/Algorithm/) + 1. [Search](/Algorithm/Search/search.hpp)——各种查找算法的实现,以及单元测试和基于google benchmark的性能测试; + 1. [std_search_examples](/Algorithm/Search/std_search_examples.cc)——stl中查找算法的例子; + 2. [Sort](/Algorithm/Sort/sort.hpp)——各种排序算法的实现,以及单元测试和基于google benchmark的性能测试; + 1. [std_sort_examples](/Algorithm/Sort/std_sort_examples.cc)——stl中排序算法的例子; +2. [AtomicQueue](/AtomicQueue/atomicqueue.hpp)——使用std::atomic实现的线程安全的队列; +3. [BinaryTree](/BinaryTree/binarytree.hpp)——二叉树的相关操作,插入、移除、查找、打印; +4. [Breakpad](/Breakpad/breakpad.hpp)——google breakpad的简单封装; +5. [ByteOrder](/ByteOrder/byteorder.hpp)——判断系统的字节序; +6. [Client](/Client/client.cpp)——一个简单的Linux select socket客户端; +7. [CountDownLatch](/CountDownLatch/countdownlatch.hpp)——使用std::mutex和std::condition_variable实现的简单倒计时门闩(std::latch c++20); +8. [Curl](/Curl/)——curl的简单使用; + 1. [TcpClient](/Curl/tcpclient.hpp)——使用curl实现的简单tcp客户端; + 2. [HttpClient](/Curl/httpclient.hpp)——使用curl实现的简单http同步客户端; + 3. [HttpClientAsync](/Curl/httpclient_async.hpp)——使用curl实现的简单http异步客户端; +9. [DesignPattern](/DesignPattern)——设计模式的一些例子; + 1. [Factory](/DesignPattern/Factory/factory.hpp)——工厂模式; + 2. [MVC](/DesignPattern/MVC/model.hpp)——mvc模式; + 3. [Observer](/DesignPattern/Observer/observer.hpp)——观察者模式; + 4. [Singleton](/DesignPattern/Singleton/singleton.hpp)——单例模式; +10. [Glog](/Glog/main.cc)——google glog的例子; +11. [Icmp](/Icmp/icmp.hpp)——linux icmp协议的简单封装; +12. [LinkedList](/LinkedList/linkedlist.hpp)——链表的相关操作,插入、移除、反转、打印; +13. [Memcpy](/Memcpy/memcpy.hpp)——`memcpy`函数实现; +14. [MonitorDir](/MonitorDir/monitordir.hpp)——windows(`ReadDirectoryChangesW`),macos(`FSEvents`)和linux(`inotify`)目录监控的简单例子; +15. [Mutex](/Mutex/mutex.hpp)——使用std::atomic_flag实现的简单互斥锁和自旋锁; +16. [OpenSSL](/OpenSSL)——openssl的一些例子; + 1. [aes](/OpenSSL/openssl_aes.cc)——aes加解密的例子; + 2. [base64](/OpenSSL/openssl_base64.cc)——base64编解码的例子; + 3. [hash](/OpenSSL/openssl_hash.cc)——sha256的例子; + 4. [hmac](/OpenSSL/openssl_hmac.cc)——hmac的例子; + 5. [pem](/OpenSSL/openssl_pem.cc)——pem格式的例子; + 6. [rsa](/OpenSSL/openssl_rsa.cc)——rsa加解密的例子; + 7. [sm4](/OpenSSL/openssl_sm4.cc)——sm4加解密的例子; + 8. [x509](/OpenSSL/openssl_x509.cc)——x509证书的例子; + 9. [bash](/OpenSSL/openssl_bash.sh)——openssl命令行的例子; +17. [Server](/Server)——linux server的一些例子; + 1. [server_epoll](/Server/server_epoll.cc)——epoll的例子; + 2. [server_poll](/Server/server_poll.cc)——poll的例子; + 3. [server_select](/Server/server_select.cc)——select的例子; +18. [Thread](/Thread/)——基于std::thread实现的线程类,包括线程池; + 1. [Thread](/Thread/thread.hpp)——线程类; + 2. [ThreadPool](/Thread/threadpool.hpp)——线程池;