├── .clang-format ├── .clang-tidy ├── .clangd ├── .gitignore ├── AppScope ├── app.json5 └── resources │ └── base │ ├── element │ └── string.json │ └── media │ └── app_icon.png ├── CMakeLists.txt ├── README.md ├── build-profile.json5 ├── build.gradle ├── cross.podspec ├── example ├── android │ ├── .gitignore │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── cross │ │ │ └── example │ │ │ └── MainActivity.java │ │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values │ │ └── styles.xml │ │ └── xml │ │ └── backup_descriptor.xml ├── harmony │ ├── .gitignore │ ├── build-profile.json5 │ ├── hvigorfile.ts │ ├── obfuscation-rules.txt │ ├── oh-package-lock.json5 │ ├── oh-package.json5 │ └── src │ │ ├── main │ │ ├── ets │ │ │ ├── harmonyability │ │ │ │ └── HarmonyAbility.ets │ │ │ ├── harmonybackupability │ │ │ │ └── HarmonyBackupAbility.ets │ │ │ └── pages │ │ │ │ └── Index.ets │ │ ├── module.json5 │ │ └── resources │ │ │ ├── base │ │ │ ├── element │ │ │ │ ├── color.json │ │ │ │ └── string.json │ │ │ ├── media │ │ │ │ ├── background.png │ │ │ │ ├── foreground.png │ │ │ │ ├── layered_image.json │ │ │ │ └── startIcon.png │ │ │ └── profile │ │ │ │ ├── backup_config.json │ │ │ │ └── main_pages.json │ │ │ ├── en_US │ │ │ └── element │ │ │ │ └── string.json │ │ │ └── zh_CN │ │ │ └── element │ │ │ └── string.json │ │ ├── mock │ │ └── mock-config.json5 │ │ ├── ohosTest │ │ ├── ets │ │ │ └── test │ │ │ │ ├── Ability.test.ets │ │ │ │ └── List.test.ets │ │ └── module.json5 │ │ └── test │ │ ├── List.test.ets │ │ └── LocalUnit.test.ets └── ios │ ├── .gitignore │ ├── Podfile │ ├── Podfile.lock │ ├── example.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── example.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── example │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── SceneDelegate.h │ ├── SceneDelegate.m │ ├── ViewController.h │ ├── ViewController.m │ ├── cross.mm │ └── main.m ├── gradle.properties ├── gradle └── wrapper │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── hvigor └── hvigor-config.json5 ├── hvigorfile.ts ├── oh-package-lock.json5 ├── oh-package.json5 ├── platforms ├── android │ ├── .gitignore │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── cpp │ │ ├── CMakeLists.txt │ │ └── cross.cpp │ │ └── java │ │ └── com │ │ └── cross │ │ └── Cross.java ├── harmony │ ├── .gitignore │ ├── BuildProfile.ets │ ├── Index.ets │ ├── build-profile.json5 │ ├── hvigorfile.ts │ ├── obfuscation-rules.txt │ ├── oh-package-lock.json5 │ ├── oh-package.json5 │ └── src │ │ ├── main │ │ ├── cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── napi_init.cpp │ │ │ └── types │ │ │ │ └── libcross │ │ │ │ ├── Index.d.ts │ │ │ │ └── oh-package.json5 │ │ ├── ets │ │ │ ├── NativeReader.ets │ │ │ ├── harmonyability │ │ │ │ └── HarmonyAbility.ets │ │ │ └── pages │ │ │ │ └── Index.ets │ │ ├── module.json5 │ │ └── resources │ │ │ ├── base │ │ │ ├── element │ │ │ │ ├── color.json │ │ │ │ └── string.json │ │ │ ├── media │ │ │ │ ├── background.png │ │ │ │ ├── foreground.png │ │ │ │ ├── layered_image.json │ │ │ │ └── startIcon.png │ │ │ └── profile │ │ │ │ └── main_pages.json │ │ │ ├── en_US │ │ │ └── element │ │ │ │ └── string.json │ │ │ └── zh_CN │ │ │ └── element │ │ │ └── string.json │ │ ├── mock │ │ ├── Libcross.mock.ets │ │ └── mock-config.json5 │ │ ├── ohosTest │ │ ├── ets │ │ │ └── test │ │ │ │ ├── Ability.test.ets │ │ │ │ └── List.test.ets │ │ └── module.json5 │ │ └── test │ │ ├── List.test.ets │ │ └── LocalUnit.test.ets └── ios │ ├── .gitignore │ └── Classes │ ├── Cross.h │ └── Cross.mm ├── settings.gradle ├── src └── url_signature │ ├── CMakeLists.txt │ ├── README.md │ ├── include │ └── url_signature.h │ └── url_signature.cpp ├── test ├── CMakeLists.txt ├── gtest │ ├── CMakeLists.txt │ ├── include │ │ └── gtest │ │ │ ├── gtest-death-test.h │ │ │ ├── gtest-matchers.h │ │ │ ├── gtest-message.h │ │ │ ├── gtest-param-test.h │ │ │ ├── gtest-printers.h │ │ │ ├── gtest-spi.h │ │ │ ├── gtest-test-part.h │ │ │ ├── gtest-typed-test.h │ │ │ ├── gtest.h │ │ │ ├── gtest_pred_impl.h │ │ │ ├── gtest_prod.h │ │ │ └── internal │ │ │ ├── custom │ │ │ ├── README.md │ │ │ ├── gtest-port.h │ │ │ ├── gtest-printers.h │ │ │ └── gtest.h │ │ │ ├── gtest-death-test-internal.h │ │ │ ├── gtest-filepath.h │ │ │ ├── gtest-internal.h │ │ │ ├── gtest-param-util.h │ │ │ ├── gtest-port-arch.h │ │ │ ├── gtest-port.h │ │ │ ├── gtest-string.h │ │ │ └── gtest-type-util.h │ └── src │ │ ├── gtest-all.cc │ │ ├── gtest-death-test.cc │ │ ├── gtest-filepath.cc │ │ ├── gtest-internal-inl.h │ │ ├── gtest-matchers.cc │ │ ├── gtest-port.cc │ │ ├── gtest-printers.cc │ │ ├── gtest-test-part.cc │ │ ├── gtest-typed-test.cc │ │ ├── gtest.cc │ │ └── gtest_main.cc ├── main.cpp └── test.cpp └── third_party ├── cxxurl ├── CMakeLists.txt ├── include │ └── cxxurl │ │ ├── string.hpp │ │ └── url.hpp └── src │ └── url.cpp └── hash ├── CMakeLists.txt ├── include ├── crc32.h ├── hash.h ├── hmac.h ├── keccak.h ├── md5.h ├── sha1.h ├── sha256.h └── sha3.h └── src ├── crc32.cpp ├── digest.cpp ├── keccak.cpp ├── md5.cpp ├── sha1.cpp ├── sha256.cpp └── sha3.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | # BasedOnStyle: LLVM 3 | ColumnLimit: 120 4 | SortIncludes: false 5 | TabWidth: 4 6 | IndentWidth: 4 7 | UseTab: Never 8 | AccessModifierOffset: -4 9 | ContinuationIndentWidth: 4 10 | IndentCaseBlocks: false 11 | IndentCaseLabels: false 12 | IndentGotoLabels: true 13 | IndentWrappedFunctionNames: false 14 | SortUsingDeclarations: false 15 | NamespaceIndentation: None 16 | SpaceAfterCStyleCast: false 17 | SpaceAfterLogicalNot: false 18 | SpaceAfterTemplateKeyword: true 19 | SpaceBeforeAssignmentOperators: true 20 | SpaceBeforeCaseColon: false 21 | SpaceBeforeCpp11BracedList: false 22 | SpaceBeforeCtorInitializerColon: true 23 | SpaceBeforeInheritanceColon: true 24 | SpaceBeforeRangeBasedForLoopColon: true 25 | SpaceBeforeSquareBrackets: false 26 | SpaceInEmptyBlock: false 27 | SpaceInEmptyParentheses: false 28 | SpacesInAngles: false 29 | SpacesInCStyleCastParentheses: false 30 | SpacesInConditionalStatement: false 31 | SpacesInParentheses: false 32 | SpacesInSquareBrackets: false 33 | AllowShortCaseLabelsOnASingleLine: false 34 | AllowShortEnumsOnASingleLine: true 35 | AllowShortFunctionsOnASingleLine: All 36 | AllowShortIfStatementsOnASingleLine: Never 37 | AllowShortLambdasOnASingleLine: All 38 | AllowShortLoopsOnASingleLine: false 39 | AlwaysBreakTemplateDeclarations: MultiLine 40 | BinPackArguments: true 41 | BinPackParameters: true 42 | BreakBeforeTernaryOperators: true 43 | BreakConstructorInitializers: BeforeColon 44 | BreakInheritanceList: BeforeColon 45 | BreakStringLiterals: true 46 | InsertBraces: false 47 | IndentExternBlock: NoIndent 48 | BreakBeforeBraces: Custom 49 | BraceWrapping: 50 | AfterCaseLabel: false 51 | AfterClass: false 52 | AfterControlStatement: Never 53 | AfterEnum: false 54 | AfterFunction: false 55 | AfterNamespace: false 56 | AfterStruct: false 57 | AfterUnion: false 58 | AfterExternBlock: false 59 | BeforeCatch: false 60 | BeforeElse: false 61 | ReflowComments: true 62 | MaxEmptyLinesToKeep: 2 -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: 'misc-missing-switch-cases,misc-napi-module-name,misc-replace-if-else-with-ternary-operator,misc-unused-local-variable,misc-unused-parameters,modernize-use-auto,readability-system-capabilities' 2 | -------------------------------------------------------------------------------- /.clangd: -------------------------------------------------------------------------------- 1 | CompileFlags: 2 | Add: [-Wunreachable-code-aggressive] 3 | Diagnostics: 4 | ClangTidy: 5 | Add: [misc-missing-switch-cases,misc-napi-module-name,misc-replace-if-else-with-ternary-operator,misc-unused-local-variable,misc-unused-parameters,modernize-use-auto,readability-system-capabilities] 6 | Remove: [] 7 | CheckOptions: 8 | misc-unused-parameters.StrictMode: true 9 | misc-unused-parameters.IgnoreVirtual: true 10 | modernize-use-auto.MinTypeNameLength: 0 11 | 12 | UnusedIncludes: Strict 13 | UnusedFunctions: Check -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | build 8 | /captures 9 | .cxx 10 | .idea 11 | cmake-build-debug 12 | gradle-wrapper.jar 13 | .vscode 14 | oh_modules 15 | .hvigor -------------------------------------------------------------------------------- /AppScope/app.json5: -------------------------------------------------------------------------------- 1 | { 2 | "app": { 3 | "bundleName": "com.taoweiji.harmony.example", 4 | "vendor": "example", 5 | "versionCode": 1000000, 6 | "versionName": "1.0.0", 7 | "icon": "$media:app_icon", 8 | "label": "$string:app_name" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /AppScope/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "app_name", 5 | "value": "MyApplication" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /AppScope/resources/base/media/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/AppScope/resources/base/media/app_icon.png -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10.2) 2 | project(cpp-android-ios-example) 3 | set(CMAKE_CXX_STANDARD 17) 4 | add_subdirectory(third_party/hash) 5 | add_subdirectory(third_party/cxxurl) 6 | add_subdirectory(src/url_signature) 7 | if (HARMONY) 8 | add_subdirectory(platforms/harmony/src/main/cpp) 9 | elseif (ANDROID) 10 | add_subdirectory(platforms/android/src/main/cpp) 11 | else () 12 | add_subdirectory(test/gtest) 13 | add_subdirectory(test) 14 | endif () -------------------------------------------------------------------------------- /build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "app": { 3 | "signingConfigs": [ 4 | { 5 | "name": "default", 6 | "type": "HarmonyOS", 7 | "material": { 8 | "certpath": "/Users/wiki/.ohos/config/default_MyApplication9_yYDzc6FLiNuw8ZxbIN_ppdzLrdax8rQZwyrpPNOvf6k=.cer", 9 | "storePassword": "0000001BAE98E175997B9584358F81F0970FC63B57B3538887D317B4AF396FE143407CC54521F5F579C862", 10 | "keyAlias": "debugKey", 11 | "keyPassword": "0000001BA023D96A0F9E14E97031D369DF17BDD1656DDD049E7C8A1C4510D4B6637844BA5D6DF2B021015B", 12 | "profile": "/Users/wiki/.ohos/config/default_MyApplication9_yYDzc6FLiNuw8ZxbIN_ppdzLrdax8rQZwyrpPNOvf6k=.p7b", 13 | "signAlg": "SHA256withECDSA", 14 | "storeFile": "/Users/wiki/.ohos/config/default_MyApplication9_yYDzc6FLiNuw8ZxbIN_ppdzLrdax8rQZwyrpPNOvf6k=.p12" 15 | } 16 | } 17 | ], 18 | "products": [ 19 | { 20 | "name": "default", 21 | "signingConfig": "default", 22 | "compatibleSdkVersion": "5.0.0(12)", 23 | "runtimeOS": "HarmonyOS", 24 | } 25 | ], 26 | "buildModeSet": [ 27 | { 28 | "name": "debug", 29 | }, 30 | { 31 | "name": "release" 32 | } 33 | ] 34 | }, 35 | "modules": [ 36 | { 37 | "name": "harmony_example", 38 | "srcPath": "./example/harmony", 39 | "targets": [ 40 | { 41 | "name": "default", 42 | "applyToProducts": [ 43 | "default" 44 | ] 45 | } 46 | ] 47 | }, 48 | { 49 | "name": "harmony", 50 | "srcPath": "./platforms/harmony", 51 | "targets": [ 52 | { 53 | "name": "default", 54 | "applyToProducts": [ 55 | "default" 56 | ] 57 | } 58 | ] 59 | } 60 | ] 61 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.cross' 2 | version '1.0' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath "com.android.tools.build:gradle:4.1.2" 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } -------------------------------------------------------------------------------- /cross.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'cross' 3 | s.version = '0.0.1' 4 | s.summary = 'cross library' 5 | s.description = 'Cross library' 6 | s.homepage = 'http://example.com' 7 | s.license = { :file => '../LICENSE' } 8 | s.author = { 'Your Company' => 'email@example.com' } 9 | s.source = { :path => '.' } 10 | # 设置源文件,切记不要把测试代码包含进来 11 | s.source_files = 'platforms/ios/Classes/**/*','third_party/**/*.{cc,cpp,h}','src/**/*.{cc,cpp,h}' 12 | # 暴露头文件,否则引用该spec的项目无法找到头文件 13 | s.public_header_files = 'platforms/ios/Classes/**/*.h','src/url_signature/include/*.h' 14 | s.platform = :ios, '9.0' 15 | # 必须配置HEADER_SEARCH_PATHS属性,是否会导致项目中C++找不到头文件 16 | s.xcconfig = { 17 | 'HEADER_SEARCH_PATHS' => '"${PODS_TARGET_SRCROOT}/third_party/cxxurl/include/" "${PODS_TARGET_SRCROOT}/third_party/hash/include/" "${PODS_TARGET_SRCROOT}/src/url_signature/include/"' 18 | } 19 | end 20 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /local.properties -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | android { 3 | compileSdkVersion 30 4 | 5 | lintOptions { 6 | disable 'InvalidPackage' 7 | } 8 | 9 | defaultConfig { 10 | applicationId "com.cross.example" 11 | minSdkVersion 16 12 | targetSdkVersion 30 13 | versionCode 1 14 | versionName "1.0" 15 | } 16 | 17 | buildTypes { 18 | release { 19 | signingConfig signingConfigs.debug 20 | } 21 | } 22 | } 23 | 24 | dependencies { 25 | implementation project(path: ':cross') 26 | } -------------------------------------------------------------------------------- /example/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /example/android/src/main/java/com/cross/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.cross.example; 2 | 3 | 4 | import android.app.Activity; 5 | import android.os.Bundle; 6 | import android.widget.TextView; 7 | 8 | import com.cross.Cross; 9 | 10 | public class MainActivity extends Activity { 11 | @Override 12 | protected void onCreate(Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_main); 15 | TextView textView = findViewById(R.id.textView); 16 | String url = "http://example.com?key2=value2&key3=value3&key1=VALUE1"; 17 | String result = Cross.signatureUrl(url); 18 | textView.setText(url + "\n" + result); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/android/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /example/android/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/example/android/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/example/android/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/example/android/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/example/android/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/example/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/android/src/main/res/xml/backup_descriptor.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/harmony/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /.preview 4 | /build 5 | /.cxx 6 | /.test -------------------------------------------------------------------------------- /example/harmony/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "apiType": "stageMode", 3 | "buildOption": { 4 | }, 5 | "buildOptionSet": [ 6 | { 7 | "name": "release", 8 | "arkOptions": { 9 | "obfuscation": { 10 | "ruleOptions": { 11 | "enable": true, 12 | "files": [ 13 | "./obfuscation-rules.txt" 14 | ] 15 | } 16 | } 17 | } 18 | }, 19 | ], 20 | "targets": [ 21 | { 22 | "name": "default" 23 | }, 24 | { 25 | "name": "ohosTest", 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /example/harmony/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { hapTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /example/harmony/obfuscation-rules.txt: -------------------------------------------------------------------------------- 1 | # Define project specific obfuscation rules here. 2 | # You can include the obfuscation configuration files in the current module's build-profile.json5. 3 | # 4 | # For more details, see 5 | # https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 6 | 7 | # Obfuscation options: 8 | # -disable-obfuscation: disable all obfuscations 9 | # -enable-property-obfuscation: obfuscate the property names 10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope 11 | # -compact: remove unnecessary blank spaces and all line feeds 12 | # -remove-log: remove all console.* statements 13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names 14 | # -apply-namecache: reuse the given cache file 15 | 16 | # Keep options: 17 | # -keep-property-name: specifies property names that you want to keep 18 | # -keep-global-name: specifies names that you want to keep in the global scope -------------------------------------------------------------------------------- /example/harmony/oh-package-lock.json5: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "stableOrder": true 4 | }, 5 | "lockfileVersion": 3, 6 | "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", 7 | "specifiers": { 8 | "harmony@../../platforms/harmony": "harmony@../../platforms/harmony", 9 | "libcross.so@../../platforms/harmony/src/main/cpp/types/libcross": "libcross.so@../../platforms/harmony/src/main/cpp/types/libcross" 10 | }, 11 | "packages": { 12 | "harmony@../../platforms/harmony": { 13 | "name": "harmony", 14 | "version": "1.0.0", 15 | "resolved": "../../platforms/harmony", 16 | "registryType": "local", 17 | "dependencies": { 18 | "libcross.so": "file:./src/main/cpp/types/libcross" 19 | } 20 | }, 21 | "libcross.so@../../platforms/harmony/src/main/cpp/types/libcross": { 22 | "name": "libcross.so", 23 | "version": "1.0.0", 24 | "resolved": "../../platforms/harmony/src/main/cpp/types/libcross", 25 | "registryType": "local" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /example/harmony/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "name": "harmony_example", 3 | "version": "1.0.0", 4 | "description": "Please describe the basic information.", 5 | "main": "", 6 | "author": "", 7 | "license": "", 8 | "dependencies": { 9 | "harmony": "file:../../platforms/harmony" 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /example/harmony/src/main/ets/harmonyability/HarmonyAbility.ets: -------------------------------------------------------------------------------- 1 | import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 2 | import { hilog } from '@kit.PerformanceAnalysisKit'; 3 | import { window } from '@kit.ArkUI'; 4 | 5 | export default class HarmonyAbility extends UIAbility { 6 | onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 7 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); 8 | } 9 | 10 | onDestroy(): void { 11 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); 12 | } 13 | 14 | onWindowStageCreate(windowStage: window.WindowStage): void { 15 | // Main window is created, set main page for this ability 16 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); 17 | 18 | windowStage.loadContent('pages/Index', (err) => { 19 | if (err.code) { 20 | hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 21 | return; 22 | } 23 | hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); 24 | }); 25 | } 26 | 27 | onWindowStageDestroy(): void { 28 | // Main window is destroyed, release UI related resources 29 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); 30 | } 31 | 32 | onForeground(): void { 33 | // Ability has brought to foreground 34 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); 35 | } 36 | 37 | onBackground(): void { 38 | // Ability has back to background 39 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /example/harmony/src/main/ets/harmonybackupability/HarmonyBackupAbility.ets: -------------------------------------------------------------------------------- 1 | import { hilog } from '@kit.PerformanceAnalysisKit'; 2 | import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; 3 | 4 | export default class HarmonyBackupAbility extends BackupExtensionAbility { 5 | async onBackup() { 6 | hilog.info(0x0000, 'testTag', 'onBackup ok'); 7 | } 8 | 9 | async onRestore(bundleVersion: BundleVersion) { 10 | hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); 11 | } 12 | } -------------------------------------------------------------------------------- /example/harmony/src/main/ets/pages/Index.ets: -------------------------------------------------------------------------------- 1 | import { NativeReader } from 'harmony' 2 | 3 | @Entry 4 | @Component 5 | struct Index { 6 | @State message: string = 'Hello World'; 7 | 8 | build() { 9 | RelativeContainer() { 10 | Text('1 + 10 = ' + new NativeReader().add(1, 10)) 11 | .fontSize(12) 12 | .fontWeight(FontWeight.Bold) 13 | .alignRules({ 14 | center: { anchor: '__container__', align: VerticalAlign.Center }, 15 | middle: { anchor: '__container__', align: HorizontalAlign.Center } 16 | }) 17 | Text(new NativeReader().signatureUrl("http://example.com?key2=value2&key3=value3&key1=VALUE1")) 18 | .fontSize(12) 19 | .margin({ top: 100 }) 20 | .fontWeight(FontWeight.Bold) 21 | .alignRules({ 22 | center: { anchor: '__container__', align: VerticalAlign.Center }, 23 | middle: { anchor: '__container__', align: HorizontalAlign.Center } 24 | }) 25 | 26 | } 27 | .height('100%') 28 | .width('100%') 29 | } 30 | } -------------------------------------------------------------------------------- /example/harmony/src/main/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "harmony_example", 4 | "type": "entry", 5 | "description": "$string:module_desc", 6 | "mainElement": "HarmonyAbility", 7 | "deviceTypes": [ 8 | "phone", 9 | "tablet", 10 | "2in1" 11 | ], 12 | "deliveryWithInstall": true, 13 | "installationFree": false, 14 | "pages": "$profile:main_pages", 15 | "abilities": [ 16 | { 17 | "name": "HarmonyAbility", 18 | "srcEntry": "./ets/harmonyability/HarmonyAbility.ets", 19 | "description": "$string:HarmonyAbility_desc", 20 | "icon": "$media:layered_image", 21 | "label": "$string:HarmonyAbility_label", 22 | "startWindowIcon": "$media:startIcon", 23 | "startWindowBackground": "$color:start_window_background", 24 | "exported": true, 25 | "skills": [ 26 | { 27 | "entities": [ 28 | "entity.system.home" 29 | ], 30 | "actions": [ 31 | "action.system.home" 32 | ] 33 | } 34 | ] 35 | } 36 | ], 37 | "extensionAbilities": [ 38 | { 39 | "name": "HarmonyBackupAbility", 40 | "srcEntry": "./ets/harmonybackupability/HarmonyBackupAbility.ets", 41 | "type": "backup", 42 | "exported": false, 43 | "metadata": [ 44 | { 45 | "name": "ohos.extension.backup", 46 | "resource": "$profile:backup_config" 47 | } 48 | ] 49 | } 50 | ] 51 | } 52 | } -------------------------------------------------------------------------------- /example/harmony/src/main/resources/base/element/color.json: -------------------------------------------------------------------------------- 1 | { 2 | "color": [ 3 | { 4 | "name": "start_window_background", 5 | "value": "#FFFFFF" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /example/harmony/src/main/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "module description" 6 | }, 7 | { 8 | "name": "HarmonyAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "HarmonyAbility_label", 13 | "value": "label" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /example/harmony/src/main/resources/base/media/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/example/harmony/src/main/resources/base/media/background.png -------------------------------------------------------------------------------- /example/harmony/src/main/resources/base/media/foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/example/harmony/src/main/resources/base/media/foreground.png -------------------------------------------------------------------------------- /example/harmony/src/main/resources/base/media/layered_image.json: -------------------------------------------------------------------------------- 1 | { 2 | "layered-image": 3 | { 4 | "background" : "$media:background", 5 | "foreground" : "$media:foreground" 6 | } 7 | } -------------------------------------------------------------------------------- /example/harmony/src/main/resources/base/media/startIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/example/harmony/src/main/resources/base/media/startIcon.png -------------------------------------------------------------------------------- /example/harmony/src/main/resources/base/profile/backup_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "allowToBackupRestore": true 3 | } -------------------------------------------------------------------------------- /example/harmony/src/main/resources/base/profile/main_pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "src": [ 3 | "pages/Index" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /example/harmony/src/main/resources/en_US/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "module description" 6 | }, 7 | { 8 | "name": "HarmonyAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "HarmonyAbility_label", 13 | "value": "label" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /example/harmony/src/main/resources/zh_CN/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "模块描述" 6 | }, 7 | { 8 | "name": "HarmonyAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "HarmonyAbility_label", 13 | "value": "label" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /example/harmony/src/mock/mock-config.json5: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /example/harmony/src/ohosTest/ets/test/Ability.test.ets: -------------------------------------------------------------------------------- 1 | import { hilog } from '@kit.PerformanceAnalysisKit'; 2 | import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; 3 | 4 | export default function abilityTest() { 5 | describe('ActsAbilityTest', () => { 6 | // Defines a test suite. Two parameters are supported: test suite name and test suite function. 7 | beforeAll(() => { 8 | // Presets an action, which is performed only once before all test cases of the test suite start. 9 | // This API supports only one parameter: preset action function. 10 | }) 11 | beforeEach(() => { 12 | // Presets an action, which is performed before each unit test case starts. 13 | // The number of execution times is the same as the number of test cases defined by **it**. 14 | // This API supports only one parameter: preset action function. 15 | }) 16 | afterEach(() => { 17 | // Presets a clear action, which is performed after each unit test case ends. 18 | // The number of execution times is the same as the number of test cases defined by **it**. 19 | // This API supports only one parameter: clear action function. 20 | }) 21 | afterAll(() => { 22 | // Presets a clear action, which is performed after all test cases of the test suite end. 23 | // This API supports only one parameter: clear action function. 24 | }) 25 | it('assertContain', 0, () => { 26 | // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. 27 | hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); 28 | let a = 'abc'; 29 | let b = 'b'; 30 | // Defines a variety of assertion methods, which are used to declare expected boolean conditions. 31 | expect(a).assertContain(b); 32 | expect(a).assertEqual(a); 33 | }) 34 | }) 35 | } -------------------------------------------------------------------------------- /example/harmony/src/ohosTest/ets/test/List.test.ets: -------------------------------------------------------------------------------- 1 | import abilityTest from './Ability.test'; 2 | 3 | export default function testsuite() { 4 | abilityTest(); 5 | } -------------------------------------------------------------------------------- /example/harmony/src/ohosTest/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "harmony_test", 4 | "type": "feature", 5 | "deviceTypes": [ 6 | "phone", 7 | "tablet", 8 | "2in1" 9 | ], 10 | "deliveryWithInstall": true, 11 | "installationFree": false 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/harmony/src/test/List.test.ets: -------------------------------------------------------------------------------- 1 | import localUnitTest from './LocalUnit.test'; 2 | 3 | export default function testsuite() { 4 | localUnitTest(); 5 | } -------------------------------------------------------------------------------- /example/harmony/src/test/LocalUnit.test.ets: -------------------------------------------------------------------------------- 1 | import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; 2 | 3 | export default function localUnitTest() { 4 | describe('localUnitTest', () => { 5 | // Defines a test suite. Two parameters are supported: test suite name and test suite function. 6 | beforeAll(() => { 7 | // Presets an action, which is performed only once before all test cases of the test suite start. 8 | // This API supports only one parameter: preset action function. 9 | }); 10 | beforeEach(() => { 11 | // Presets an action, which is performed before each unit test case starts. 12 | // The number of execution times is the same as the number of test cases defined by **it**. 13 | // This API supports only one parameter: preset action function. 14 | }); 15 | afterEach(() => { 16 | // Presets a clear action, which is performed after each unit test case ends. 17 | // The number of execution times is the same as the number of test cases defined by **it**. 18 | // This API supports only one parameter: clear action function. 19 | }); 20 | afterAll(() => { 21 | // Presets a clear action, which is performed after all test cases of the test suite end. 22 | // This API supports only one parameter: clear action function. 23 | }); 24 | it('assertContain', 0, () => { 25 | // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. 26 | let a = 'abc'; 27 | let b = 'b'; 28 | // Defines a variety of assertion methods, which are used to declare expected boolean conditions. 29 | expect(a).assertContain(b); 30 | expect(a).assertEqual(a); 31 | }); 32 | }); 33 | } -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '9.0' 2 | use_frameworks! 3 | 4 | target 'example' do 5 | pod 'cross', :path => '../../' 6 | end 7 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - cross (0.0.1) 3 | 4 | DEPENDENCIES: 5 | - cross (from `../../`) 6 | 7 | EXTERNAL SOURCES: 8 | cross: 9 | :path: "../../" 10 | 11 | SPEC CHECKSUMS: 12 | cross: df12eb640eb57547c4501973fbe9581eaa3ac21a 13 | 14 | PODFILE CHECKSUM: 802d9961bd6aa896e109ea6e40b6aa7a2939a1d2 15 | 16 | COCOAPODS: 1.15.2 17 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // example 4 | // 5 | // Created by Wiki on 2021/2/19. 6 | // 7 | 8 | #import 9 | 10 | @interface AppDelegate : UIResponder 11 | 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // example 4 | // 5 | // Created by Wiki on 2021/2/19. 6 | // 7 | 8 | #import "AppDelegate.h" 9 | 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | 21 | return YES; 22 | } 23 | 24 | 25 | #pragma mark - UISceneSession lifecycle 26 | 27 | 28 | - (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { 29 | // Called when a new scene session is being created. 30 | // Use this method to select a configuration to create the new scene with. 31 | return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role]; 32 | } 33 | 34 | 35 | - (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { 36 | // Called when the user discards a scene session. 37 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 38 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 39 | } 40 | 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /example/ios/example/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /example/ios/example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /example/ios/example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/example/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /example/ios/example/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /example/ios/example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UIApplicationSupportsIndirectInputEvents 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIMainStoryboardFile 47 | Main 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | 52 | UISupportedInterfaceOrientations 53 | 54 | UIInterfaceOrientationPortrait 55 | UIInterfaceOrientationLandscapeLeft 56 | UIInterfaceOrientationLandscapeRight 57 | 58 | UISupportedInterfaceOrientations~ipad 59 | 60 | UIInterfaceOrientationPortrait 61 | UIInterfaceOrientationPortraitUpsideDown 62 | UIInterfaceOrientationLandscapeLeft 63 | UIInterfaceOrientationLandscapeRight 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /example/ios/example/SceneDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.h 3 | // example 4 | // 5 | // Created by Wiki on 2021/2/19. 6 | // 7 | 8 | #import 9 | 10 | @interface SceneDelegate : UIResponder 11 | 12 | @property (strong, nonatomic) UIWindow * window; 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /example/ios/example/SceneDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.m 3 | // example 4 | // 5 | // Created by Wiki on 2021/2/19. 6 | // 7 | 8 | #import "SceneDelegate.h" 9 | 10 | @interface SceneDelegate () 11 | 12 | @end 13 | 14 | @implementation SceneDelegate 15 | 16 | 17 | - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { 18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 21 | } 22 | 23 | 24 | - (void)sceneDidDisconnect:(UIScene *)scene { 25 | // Called as the scene is being released by the system. 26 | // This occurs shortly after the scene enters the background, or when its session is discarded. 27 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 28 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 29 | } 30 | 31 | 32 | - (void)sceneDidBecomeActive:(UIScene *)scene { 33 | // Called when the scene has moved from an inactive state to an active state. 34 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 35 | } 36 | 37 | 38 | - (void)sceneWillResignActive:(UIScene *)scene { 39 | // Called when the scene will move from an active state to an inactive state. 40 | // This may occur due to temporary interruptions (ex. an incoming phone call). 41 | } 42 | 43 | 44 | - (void)sceneWillEnterForeground:(UIScene *)scene { 45 | // Called as the scene transitions from the background to the foreground. 46 | // Use this method to undo the changes made on entering the background. 47 | } 48 | 49 | 50 | - (void)sceneDidEnterBackground:(UIScene *)scene { 51 | // Called as the scene transitions from the foreground to the background. 52 | // Use this method to save data, release shared resources, and store enough scene-specific state information 53 | // to restore the scene back to its current state. 54 | } 55 | 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /example/ios/example/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // example 4 | // 5 | // Created by Wiki on 2021/2/19. 6 | // 7 | 8 | #import 9 | 10 | @interface ViewController : UIViewController 11 | 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /example/ios/example/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // example 4 | // 5 | // Created by Wiki on 2021/2/19. 6 | // 7 | 8 | #import "ViewController.h" 9 | #import "Cross.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | NSString* url = @"http://example.com?key2=value2&key3=value3&key1=VALUE1"; 20 | Cross *cross = [[Cross alloc] init]; 21 | NSString*newUrl = [cross signatureUrl:url]; 22 | NSLog(url); 23 | NSLog(newUrl); 24 | // Do any additional setup after loading the view. 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /example/ios/example/cross.mm: -------------------------------------------------------------------------------- 1 | // 2 | // cross.h 3 | // example 4 | // 5 | // Created by Wiki on 2021/2/19. 6 | // 7 | 8 | #i 9 | -------------------------------------------------------------------------------- /example/ios/example/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // example 4 | // 5 | // Created by Wiki on 2021/2/19. 6 | // 7 | 8 | #import 9 | #import "AppDelegate.h" 10 | 11 | int main(int argc, char * argv[]) { 12 | NSString * appDelegateClassName; 13 | @autoreleasepool { 14 | // Setup code that might create autoreleased objects goes here. 15 | appDelegateClassName = NSStringFromClass([AppDelegate class]); 16 | } 17 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 18 | } 19 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Oct 18 14:48:41 CST 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://mirrors.aliyun.com/macports/distfiles/gradle/gradle-6.5-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /hvigor/hvigor-config.json5: -------------------------------------------------------------------------------- 1 | { 2 | "modelVersion": "5.0.0", 3 | "dependencies": { 4 | }, 5 | "execution": { 6 | // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ 7 | // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ 8 | // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ 9 | // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ 10 | // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ 11 | }, 12 | "logging": { 13 | // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ 14 | }, 15 | "debugging": { 16 | // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ 17 | }, 18 | "nodeOptions": { 19 | // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ 20 | // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { appTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /oh-package-lock.json5: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "stableOrder": true 4 | }, 5 | "lockfileVersion": 3, 6 | "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", 7 | "specifiers": { 8 | "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", 9 | "@ohos/hypium@1.0.18": "@ohos/hypium@1.0.18" 10 | }, 11 | "packages": { 12 | "@ohos/hamock@1.0.0": { 13 | "name": "@ohos/hamock", 14 | "version": "1.0.0", 15 | "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", 16 | "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hamock/-/hamock-1.0.0.har", 17 | "registryType": "ohpm" 18 | }, 19 | "@ohos/hypium@1.0.18": { 20 | "name": "@ohos/hypium", 21 | "version": "1.0.18", 22 | "integrity": "sha512-RGe/iLGdeywdQilMWZsHKUoiE9OJ+9QxQsorF92R2ImLNVHVhbpSePNITGpW7TnvLgOIP/jscOqfIOhk6X7XRQ==", 23 | "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.18.har", 24 | "registryType": "ohpm" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "modelVersion": "5.0.0", 3 | "description": "Please describe the basic information.", 4 | "dependencies": { 5 | }, 6 | "devDependencies": { 7 | "@ohos/hypium": "1.0.18", 8 | "@ohos/hamock": "1.0.0" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /platforms/android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .cxx 10 | .idea -------------------------------------------------------------------------------- /platforms/android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 30 5 | buildToolsVersion "30.0.2" 6 | 7 | defaultConfig { 8 | minSdkVersion 16 9 | targetSdkVersion 30 10 | 11 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 12 | consumerProguardFiles "consumer-rules.pro" 13 | externalNativeBuild { 14 | cmake { 15 | cppFlags "" 16 | } 17 | } 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | compileOptions { 27 | sourceCompatibility JavaVersion.VERSION_1_8 28 | targetCompatibility JavaVersion.VERSION_1_8 29 | } 30 | externalNativeBuild { 31 | cmake { 32 | // 这里需要指向项目根目录的 CMakeLists.txt 文件 33 | path "../../CMakeLists.txt" 34 | version "3.10.2" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /platforms/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /platforms/android/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10.2) 2 | project("cross") 3 | include_directories(export_include) 4 | add_library(${PROJECT_NAME} SHARED cross.cpp) 5 | find_library(log-lib log) 6 | target_link_libraries(${PROJECT_NAME} ${log-lib} url_signature) -------------------------------------------------------------------------------- /platforms/android/src/main/cpp/cross.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "url_signature.h" 4 | 5 | JavaVM *jvm = nullptr; 6 | 7 | JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { 8 | JNIEnv *env = nullptr; 9 | if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) { 10 | return JNI_ERR; 11 | } 12 | jvm = vm; 13 | return JNI_VERSION_1_6; 14 | } 15 | 16 | void GetJNIEnv(JNIEnv *&env) { 17 | int status = jvm->GetEnv((void **) &env, JNI_VERSION_1_6); 18 | // 获取当前native线程是否有没有被附加到jvm环境中 19 | if (status == JNI_EDETACHED) { 20 | // 如果没有, 主动附加到jvm环境中,获取到env 21 | if (jvm->AttachCurrentThread(&env, nullptr) != JNI_OK) { 22 | // Failed to attach 23 | } 24 | } else if (status == JNI_OK) { 25 | // success 26 | } else if (status == JNI_EVERSION) { 27 | // GetEnv: version not supported 28 | } 29 | } 30 | 31 | void test() { 32 | JNIEnv *env; 33 | GetJNIEnv(env); 34 | jstring jstr = env->NewStringUTF("hello world"); 35 | } 36 | 37 | 38 | extern "C" 39 | JNIEXPORT jstring JNICALL 40 | Java_com_cross_Cross_signatureUrl(JNIEnv *env, jclass clazz, jstring j_url) { 41 | const char *url = env->GetStringUTFChars(j_url, JNI_FALSE); 42 | auto result = env->NewStringUTF(SignatureUrl(url).c_str()); 43 | env->ReleaseStringUTFChars(j_url, url); 44 | return result; 45 | } -------------------------------------------------------------------------------- /platforms/android/src/main/java/com/cross/Cross.java: -------------------------------------------------------------------------------- 1 | package com.cross; 2 | 3 | public class Cross { 4 | static { 5 | System.loadLibrary("cross"); 6 | } 7 | public static native String signatureUrl(String url); 8 | } 9 | -------------------------------------------------------------------------------- /platforms/harmony/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /oh_modules 3 | /.preview 4 | /build 5 | /.cxx 6 | /.test -------------------------------------------------------------------------------- /platforms/harmony/BuildProfile.ets: -------------------------------------------------------------------------------- 1 | /** 2 | * Use these variables when you tailor your ArkTS code. They must be of the const type. 3 | */ 4 | export const HAR_VERSION = '1.0.0'; 5 | export const BUILD_MODE_NAME = 'debug'; 6 | export const DEBUG = true; 7 | export const TARGET_NAME = 'default'; 8 | 9 | /** 10 | * BuildProfile Class is used only for compatibility purposes. 11 | */ 12 | export default class BuildProfile { 13 | static readonly HAR_VERSION = HAR_VERSION; 14 | static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; 15 | static readonly DEBUG = DEBUG; 16 | static readonly TARGET_NAME = TARGET_NAME; 17 | } -------------------------------------------------------------------------------- /platforms/harmony/Index.ets: -------------------------------------------------------------------------------- 1 | export { NativeReader } from './src/main/ets/NativeReader' 2 | -------------------------------------------------------------------------------- /platforms/harmony/build-profile.json5: -------------------------------------------------------------------------------- 1 | { 2 | "apiType": "stageMode", 3 | "buildOption": { 4 | "externalNativeOptions": { 5 | "path": "../../CMakeLists.txt", 6 | "arguments": "-DHARMONY=TRUE", 7 | "cppFlags": "" 8 | } 9 | }, 10 | "buildOptionSet": [ 11 | { 12 | "name": "release", 13 | "arkOptions": { 14 | "obfuscation": { 15 | "ruleOptions": { 16 | "enable": true, 17 | "files": [ 18 | "./obfuscation-rules.txt" 19 | ] 20 | } 21 | } 22 | }, 23 | "nativeLib": { 24 | "debugSymbol": { 25 | "strip": true, 26 | "exclude": [] 27 | } 28 | } 29 | }, 30 | ], 31 | "targets": [ 32 | { 33 | "name": "default" 34 | }, 35 | { 36 | "name": "ohosTest", 37 | } 38 | ] 39 | } -------------------------------------------------------------------------------- /platforms/harmony/hvigorfile.ts: -------------------------------------------------------------------------------- 1 | import { harTasks } from '@ohos/hvigor-ohos-plugin'; 2 | 3 | export default { 4 | system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ 5 | plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ 6 | } 7 | -------------------------------------------------------------------------------- /platforms/harmony/obfuscation-rules.txt: -------------------------------------------------------------------------------- 1 | # Define project specific obfuscation rules here. 2 | # You can include the obfuscation configuration files in the current module's build-profile.json5. 3 | # 4 | # For more details, see 5 | # https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 6 | 7 | # Obfuscation options: 8 | # -disable-obfuscation: disable all obfuscations 9 | # -enable-property-obfuscation: obfuscate the property names 10 | # -enable-toplevel-obfuscation: obfuscate the names in the global scope 11 | # -compact: remove unnecessary blank spaces and all line feeds 12 | # -remove-log: remove all console.* statements 13 | # -print-namecache: print the name cache that contains the mapping from the old names to new names 14 | # -apply-namecache: reuse the given cache file 15 | 16 | # Keep options: 17 | # -keep-property-name: specifies property names that you want to keep 18 | # -keep-global-name: specifies names that you want to keep in the global scope -------------------------------------------------------------------------------- /platforms/harmony/oh-package-lock.json5: -------------------------------------------------------------------------------- 1 | { 2 | "meta": { 3 | "stableOrder": true 4 | }, 5 | "lockfileVersion": 3, 6 | "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", 7 | "specifiers": { 8 | "libcross.so@src/main/cpp/types/libcross": "libcross.so@src/main/cpp/types/libcross" 9 | }, 10 | "packages": { 11 | "libcross.so@src/main/cpp/types/libcross": { 12 | "name": "libcross.so", 13 | "version": "1.0.0", 14 | "resolved": "src/main/cpp/types/libcross", 15 | "registryType": "local" 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /platforms/harmony/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "name": "harmony", 3 | "version": "1.0.0", 4 | "description": "Please describe the basic information.", 5 | "main": "Index.ets", 6 | "author": "", 7 | "license": "", 8 | "dependencies": { 9 | "libcross.so": "file:./src/main/cpp/types/libcross" 10 | } 11 | } -------------------------------------------------------------------------------- /platforms/harmony/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # the minimum version of CMake. 2 | cmake_minimum_required(VERSION 3.4.1) 3 | project("cross") 4 | include_directories(export_include) 5 | set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) 6 | 7 | if(DEFINED PACKAGE_FIND_FILE) 8 | include(${PACKAGE_FIND_FILE}) 9 | endif() 10 | 11 | include_directories(${NATIVERENDER_ROOT_PATH} 12 | ${NATIVERENDER_ROOT_PATH}/include) 13 | 14 | add_library(${PROJECT_NAME} SHARED napi_init.cpp) 15 | target_link_libraries(${PROJECT_NAME} PUBLIC libace_napi.z.so url_signature) 16 | #target_link_libraries(${PROJECT_NAME} url_signature) 17 | 18 | 19 | #cmake_minimum_required(VERSION 3.10.2) 20 | #project("cross") 21 | #include_directories(export_include) 22 | #add_library(${PROJECT_NAME} SHARED cross.cpp) 23 | #find_library(log-lib log) 24 | #target_link_libraries(${PROJECT_NAME} ${log-lib} url_signature) -------------------------------------------------------------------------------- /platforms/harmony/src/main/cpp/napi_init.cpp: -------------------------------------------------------------------------------- 1 | #include "napi/native_api.h" 2 | #include "url_signature.h" 3 | 4 | static napi_value Add(napi_env env, napi_callback_info info) { 5 | size_t argc = 2; 6 | napi_value args[2] = {nullptr}; 7 | 8 | napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 9 | 10 | napi_valuetype valuetype0; 11 | napi_typeof(env, args[0], &valuetype0); 12 | 13 | napi_valuetype valuetype1; 14 | napi_typeof(env, args[1], &valuetype1); 15 | 16 | double value0; 17 | napi_get_value_double(env, args[0], &value0); 18 | 19 | double value1; 20 | napi_get_value_double(env, args[1], &value1); 21 | 22 | napi_value sum; 23 | napi_create_double(env, value0 + value1, &sum); 24 | 25 | std::string str = SignatureUrl(""); 26 | 27 | return sum; 28 | } 29 | 30 | static std::string value2String(napi_env env, napi_value value) { 31 | size_t stringSize = 0; 32 | napi_get_value_string_utf8(env, value, nullptr, 0, &stringSize); // 获取字符串长度 33 | char buff[stringSize + 1]; 34 | napi_get_value_string_utf8(env, value, buff, stringSize + 1, &stringSize); // 根据长度传换成字符串 35 | return buff; 36 | } 37 | 38 | static napi_value SignatureUrl(napi_env env, napi_callback_info info) { 39 | size_t argc = 1; 40 | napi_value args[1] = {nullptr}; 41 | napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 42 | napi_value str = args[0]; // args[0]->string 43 | std::string stringValue = value2String(env, str); // 将 str 转换成 string 类型 44 | std::string result = SignatureUrl(stringValue); 45 | napi_value sum; 46 | napi_create_string_utf8(env, result.c_str(), result.length(), &sum); 47 | return sum; 48 | } 49 | 50 | 51 | EXTERN_C_START 52 | static napi_value Init(napi_env env, napi_value exports) { 53 | napi_property_descriptor desc[] = { 54 | {"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr}, 55 | {"signatureUrl", nullptr, SignatureUrl, nullptr, nullptr, nullptr, napi_default, nullptr}}; 56 | napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 57 | return exports; 58 | } 59 | EXTERN_C_END 60 | 61 | static napi_module demoModule = { 62 | .nm_version = 1, 63 | .nm_flags = 0, 64 | .nm_filename = nullptr, 65 | .nm_register_func = Init, 66 | .nm_modname = "cross", 67 | .nm_priv = ((void *)0), 68 | .reserved = {0}, 69 | }; 70 | 71 | extern "C" __attribute__((constructor)) void RegisterHarmonyModule(void) { napi_module_register(&demoModule); } 72 | -------------------------------------------------------------------------------- /platforms/harmony/src/main/cpp/types/libcross/Index.d.ts: -------------------------------------------------------------------------------- 1 | export const add: (a: number, b: number) => number; 2 | export const signatureUrl: (url: string) => string; -------------------------------------------------------------------------------- /platforms/harmony/src/main/cpp/types/libcross/oh-package.json5: -------------------------------------------------------------------------------- 1 | { 2 | "name": "libcross.so", 3 | "types": "./Index.d.ts", 4 | "version": "1.0.0", 5 | "description": "Please describe the basic information." 6 | } -------------------------------------------------------------------------------- /platforms/harmony/src/main/ets/NativeReader.ets: -------------------------------------------------------------------------------- 1 | import testNapi from 'libcross.so'; 2 | 3 | export class NativeReader { 4 | add(a: number, b: number): number { 5 | return testNapi.add(a, b); 6 | } 7 | signatureUrl(url: string): string { 8 | return testNapi.signatureUrl(url); 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /platforms/harmony/src/main/ets/harmonyability/HarmonyAbility.ets: -------------------------------------------------------------------------------- 1 | import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 2 | import { hilog } from '@kit.PerformanceAnalysisKit'; 3 | import { window } from '@kit.ArkUI'; 4 | 5 | export default class HarmonyAbility extends UIAbility { 6 | onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 7 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); 8 | } 9 | 10 | onDestroy(): void { 11 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); 12 | } 13 | 14 | onWindowStageCreate(windowStage: window.WindowStage): void { 15 | // Main window is created, set main page for this ability 16 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); 17 | 18 | windowStage.loadContent('pages/Index', (err) => { 19 | if (err.code) { 20 | hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); 21 | return; 22 | } 23 | hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); 24 | }); 25 | } 26 | 27 | onWindowStageDestroy(): void { 28 | // Main window is destroyed, release UI related resources 29 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); 30 | } 31 | 32 | onForeground(): void { 33 | // Ability has brought to foreground 34 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); 35 | } 36 | 37 | onBackground(): void { 38 | // Ability has back to background 39 | hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /platforms/harmony/src/main/ets/pages/Index.ets: -------------------------------------------------------------------------------- 1 | import { hilog } from '@kit.PerformanceAnalysisKit'; 2 | import testNapi from 'libcross.so'; 3 | 4 | @Entry 5 | @Component 6 | struct Index { 7 | @State message: string = 'Hello World'; 8 | 9 | build() { 10 | Row() { 11 | Column() { 12 | Text(this.message) 13 | .fontSize(50) 14 | .fontWeight(FontWeight.Bold) 15 | .onClick(() => { 16 | hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.add(2, 3)); 17 | }) 18 | } 19 | .width('100%') 20 | } 21 | .height('100%') 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /platforms/harmony/src/main/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "harmony", 4 | "type": "har", 5 | "deviceTypes": [ 6 | "phone", 7 | "tablet", 8 | "2in1" 9 | ], 10 | "abilities": [ 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /platforms/harmony/src/main/resources/base/element/color.json: -------------------------------------------------------------------------------- 1 | { 2 | "color": [ 3 | { 4 | "name": "start_window_background", 5 | "value": "#FFFFFF" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /platforms/harmony/src/main/resources/base/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "module description" 6 | }, 7 | { 8 | "name": "HarmonyAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "HarmonyAbility_label", 13 | "value": "label" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /platforms/harmony/src/main/resources/base/media/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/platforms/harmony/src/main/resources/base/media/background.png -------------------------------------------------------------------------------- /platforms/harmony/src/main/resources/base/media/foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/platforms/harmony/src/main/resources/base/media/foreground.png -------------------------------------------------------------------------------- /platforms/harmony/src/main/resources/base/media/layered_image.json: -------------------------------------------------------------------------------- 1 | { 2 | "layered-image": 3 | { 4 | "background" : "$media:background", 5 | "foreground" : "$media:foreground" 6 | } 7 | } -------------------------------------------------------------------------------- /platforms/harmony/src/main/resources/base/media/startIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taoweiji/cpp-android-ios-example/8647fa5aa89e43fd5705e07e1437b553c2405785/platforms/harmony/src/main/resources/base/media/startIcon.png -------------------------------------------------------------------------------- /platforms/harmony/src/main/resources/base/profile/main_pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "src": [ 3 | "pages/Index" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /platforms/harmony/src/main/resources/en_US/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "module description" 6 | }, 7 | { 8 | "name": "HarmonyAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "HarmonyAbility_label", 13 | "value": "label" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /platforms/harmony/src/main/resources/zh_CN/element/string.json: -------------------------------------------------------------------------------- 1 | { 2 | "string": [ 3 | { 4 | "name": "module_desc", 5 | "value": "模块描述" 6 | }, 7 | { 8 | "name": "HarmonyAbility_desc", 9 | "value": "description" 10 | }, 11 | { 12 | "name": "HarmonyAbility_label", 13 | "value": "label" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /platforms/harmony/src/mock/Libcross.mock.ets: -------------------------------------------------------------------------------- 1 | const NativeMock: Record = { 2 | 'add': (a: number, b: number) => { 3 | return a + b; 4 | }, 5 | }; 6 | 7 | export default NativeMock; -------------------------------------------------------------------------------- /platforms/harmony/src/mock/mock-config.json5: -------------------------------------------------------------------------------- 1 | { 2 | "libcross.so": { 3 | "source": "src/mock/Libcross.mock.ets" 4 | } 5 | } -------------------------------------------------------------------------------- /platforms/harmony/src/ohosTest/ets/test/Ability.test.ets: -------------------------------------------------------------------------------- 1 | import { hilog } from '@kit.PerformanceAnalysisKit'; 2 | import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; 3 | 4 | export default function abilityTest() { 5 | describe('ActsAbilityTest', () => { 6 | // Defines a test suite. Two parameters are supported: test suite name and test suite function. 7 | beforeAll(() => { 8 | // Presets an action, which is performed only once before all test cases of the test suite start. 9 | // This API supports only one parameter: preset action function. 10 | }) 11 | beforeEach(() => { 12 | // Presets an action, which is performed before each unit test case starts. 13 | // The number of execution times is the same as the number of test cases defined by **it**. 14 | // This API supports only one parameter: preset action function. 15 | }) 16 | afterEach(() => { 17 | // Presets a clear action, which is performed after each unit test case ends. 18 | // The number of execution times is the same as the number of test cases defined by **it**. 19 | // This API supports only one parameter: clear action function. 20 | }) 21 | afterAll(() => { 22 | // Presets a clear action, which is performed after all test cases of the test suite end. 23 | // This API supports only one parameter: clear action function. 24 | }) 25 | it('assertContain', 0, () => { 26 | // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. 27 | hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); 28 | let a = 'abc'; 29 | let b = 'b'; 30 | // Defines a variety of assertion methods, which are used to declare expected boolean conditions. 31 | expect(a).assertContain(b); 32 | expect(a).assertEqual(a); 33 | }) 34 | }) 35 | } -------------------------------------------------------------------------------- /platforms/harmony/src/ohosTest/ets/test/List.test.ets: -------------------------------------------------------------------------------- 1 | import abilityTest from './Ability.test'; 2 | 3 | export default function testsuite() { 4 | abilityTest(); 5 | } -------------------------------------------------------------------------------- /platforms/harmony/src/ohosTest/module.json5: -------------------------------------------------------------------------------- 1 | { 2 | "module": { 3 | "name": "harmony_test", 4 | "type": "har", 5 | "deviceTypes": [ 6 | "phone", 7 | "tablet", 8 | "2in1" 9 | ], 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /platforms/harmony/src/test/List.test.ets: -------------------------------------------------------------------------------- 1 | import localUnitTest from './LocalUnit.test'; 2 | 3 | export default function testsuite() { 4 | localUnitTest(); 5 | } -------------------------------------------------------------------------------- /platforms/harmony/src/test/LocalUnit.test.ets: -------------------------------------------------------------------------------- 1 | import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; 2 | 3 | export default function localUnitTest() { 4 | describe('localUnitTest', () => { 5 | // Defines a test suite. Two parameters are supported: test suite name and test suite function. 6 | beforeAll(() => { 7 | // Presets an action, which is performed only once before all test cases of the test suite start. 8 | // This API supports only one parameter: preset action function. 9 | }); 10 | beforeEach(() => { 11 | // Presets an action, which is performed before each unit test case starts. 12 | // The number of execution times is the same as the number of test cases defined by **it**. 13 | // This API supports only one parameter: preset action function. 14 | }); 15 | afterEach(() => { 16 | // Presets a clear action, which is performed after each unit test case ends. 17 | // The number of execution times is the same as the number of test cases defined by **it**. 18 | // This API supports only one parameter: clear action function. 19 | }); 20 | afterAll(() => { 21 | // Presets a clear action, which is performed after all test cases of the test suite end. 22 | // This API supports only one parameter: clear action function. 23 | }); 24 | it('assertContain', 0, () => { 25 | // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. 26 | let a = 'abc'; 27 | let b = 'b'; 28 | // Defines a variety of assertion methods, which are used to declare expected boolean conditions. 29 | expect(a).assertContain(b); 30 | expect(a).assertEqual(a); 31 | }); 32 | }); 33 | } -------------------------------------------------------------------------------- /platforms/ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /platforms/ios/Classes/Cross.h: -------------------------------------------------------------------------------- 1 | 2 | @interface Cross : NSObject 3 | - (NSString*)signatureUrl:(NSString *)url; 4 | @end 5 | -------------------------------------------------------------------------------- /platforms/ios/Classes/Cross.mm: -------------------------------------------------------------------------------- 1 | #import "Cross.h" 2 | #include 3 | #include 4 | 5 | @implementation Cross 6 | - (NSString*)signatureUrl:(NSString *)url{ 7 | std::string str = [url UTF8String]; 8 | std::string result = SignatureUrl(str); 9 | NSString *newUrl = [NSString stringWithUTF8String:result.c_str()]; 10 | return newUrl; 11 | } 12 | @end 13 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'cpp-android-ios-example' 2 | include ":cross" 3 | project(":cross").projectDir = new File("platforms/android") 4 | include ":example" 5 | project(":example").projectDir = new File("example/android") -------------------------------------------------------------------------------- /src/url_signature/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10.2) 2 | set(CMAKE_CXX_STANDARD 14) 3 | project(url_signature) 4 | add_library(${PROJECT_NAME} url_signature.cpp) 5 | target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include) 6 | target_link_libraries(${PROJECT_NAME} cxxurl hash) -------------------------------------------------------------------------------- /src/url_signature/README.md: -------------------------------------------------------------------------------- 1 | # URL签名 2 | 1. 约定密钥:1bc29b36f623ba82aaf6724fd3b16718 3 | 2. http://example.com?key1=VALUE1&key2=value2&key3=value3 4 | 3. 对参数的name进行排序后拼接获得 key1VALUE1key2value2key3value3 5 | 4. 拼接后的参数+特定的私钥组合成 key1VALUE1key2value2key3value31bc29b36f623ba82aaf6724fd3b16718 6 | 5. 对拼接后的参数转换成小写key1value1key2value2key3value31bc29b36f623ba82aaf6724fd3b16718 7 | 6. 然后执行md5,得到签名字符串 5779f1cd4693e8b3c5981d37d20aa331 8 | 7. 这个签名字符串也需要放到参数后一起请求服务端,http://example.com?key1=VALUE1&key2=value2&key3=value3&sign=5779f1cd4693e8b3c5981d37d20aa331 9 | 10 | > 这个是标准URL签名方式,密钥放在服务端和C++代码中,这个密钥不能让外部人员知晓 -------------------------------------------------------------------------------- /src/url_signature/include/url_signature.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Wiki on 2021/2/18. 3 | // 4 | 5 | #ifndef CPP_ANDROID_IOS_MULTI_PLATFORM_URL_SIGNATURE_H 6 | #define CPP_ANDROID_IOS_MULTI_PLATFORM_URL_SIGNATURE_H 7 | #include 8 | std::string SignatureUrl(const std::string &url); 9 | 10 | #endif //CPP_ANDROID_IOS_MULTI_PLATFORM_URL_SIGNATURE_H 11 | -------------------------------------------------------------------------------- /src/url_signature/url_signature.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Wiki on 2021/2/18. 3 | // 4 | 5 | #include "url_signature.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | const string SIGNATURE_URL_SECRET = "1bc29b36f623ba82aaf6724fd3b16718"; 13 | 14 | string SignatureUrl(const string &url) { 15 | Url u(url); 16 | map params; 17 | vector keys; 18 | for (int i = 0; i < u.query().size(); ++i) { 19 | Url::KeyVal keyVal = u.query(i); 20 | keys.push_back(keyVal.key()); 21 | params[keyVal.key()] = keyVal.val(); 22 | } 23 | // 排序 24 | sort(keys.begin(), keys.end()); 25 | string str; 26 | for (auto &key : keys) { 27 | str += key; 28 | str += params[key]; 29 | } 30 | // 拼接密钥到字符串的后面 31 | str += SIGNATURE_URL_SECRET; 32 | // 转成小写 33 | transform(str.begin(), str.end(), str.begin(), ::tolower); 34 | // 计算md5 35 | MD5 md5; 36 | md5.reset(); 37 | md5.add(str.c_str(), str.length()); 38 | // 添加md5到url 39 | u.add_query("sign", md5.getHash()); 40 | return u.str(); 41 | } -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10.2) 2 | project(test) 3 | # 添加可执行代码 4 | add_executable(${PROJECT_NAME} main.cpp test.cpp) 5 | # 添加库依赖 6 | target_link_libraries(${PROJECT_NAME} gtest url_signature) -------------------------------------------------------------------------------- /test/gtest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10.2) 2 | set(CMAKE_CXX_STANDARD 17) 3 | set(CMAKE_CXX_EXTENSIONS OFF) 4 | project(gtest) 5 | include_directories(.) 6 | add_library(${PROJECT_NAME} src/gtest-all.cc) 7 | # 定义需要暴露的头文件 8 | target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include) -------------------------------------------------------------------------------- /test/gtest/include/gtest/gtest-message.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // The Google C++ Testing and Mocking Framework (Google Test) 32 | // 33 | // This header file defines the Message class. 34 | // 35 | // IMPORTANT NOTE: Due to limitation of the C++ language, we have to 36 | // leave some internal implementation details in this header file. 37 | // They are clearly marked by comments like this: 38 | // 39 | // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 40 | // 41 | // Such code is NOT meant to be used by a user directly, and is subject 42 | // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user 43 | // program! 44 | 45 | // GOOGLETEST_CM0001 DO NOT DELETE 46 | 47 | #ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 48 | #define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 49 | 50 | #include 51 | #include 52 | #include 53 | 54 | #include "gtest/internal/gtest-port.h" 55 | 56 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 57 | /* class A needs to have dll-interface to be used by clients of class B */) 58 | 59 | // Ensures that there is at least one operator<< in the global namespace. 60 | // See Message& operator<<(...) below for why. 61 | void operator<<(const testing::internal::Secret&, int); 62 | 63 | namespace testing { 64 | 65 | // The Message class works like an ostream repeater. 66 | // 67 | // Typical usage: 68 | // 69 | // 1. You stream a bunch of values to a Message object. 70 | // It will remember the text in a stringstream. 71 | // 2. Then you stream the Message object to an ostream. 72 | // This causes the text in the Message to be streamed 73 | // to the ostream. 74 | // 75 | // For example; 76 | // 77 | // testing::Message foo; 78 | // foo << 1 << " != " << 2; 79 | // std::cout << foo; 80 | // 81 | // will print "1 != 2". 82 | // 83 | // Message is not intended to be inherited from. In particular, its 84 | // destructor is not virtual. 85 | // 86 | // Note that stringstream behaves differently in gcc and in MSVC. You 87 | // can stream a NULL char pointer to it in the former, but not in the 88 | // latter (it causes an access violation if you do). The Message 89 | // class hides this difference by treating a NULL char pointer as 90 | // "(null)". 91 | class GTEST_API_ Message { 92 | private: 93 | // The type of basic IO manipulators (endl, ends, and flush) for 94 | // narrow streams. 95 | typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); 96 | 97 | public: 98 | // Constructs an empty Message. 99 | Message(); 100 | 101 | // Copy constructor. 102 | Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT 103 | *ss_ << msg.GetString(); 104 | } 105 | 106 | // Constructs a Message from a C-string. 107 | explicit Message(const char* str) : ss_(new ::std::stringstream) { 108 | *ss_ << str; 109 | } 110 | 111 | // Streams a non-pointer value to this object. 112 | template 113 | inline Message& operator <<(const T& val) { 114 | // Some libraries overload << for STL containers. These 115 | // overloads are defined in the global namespace instead of ::std. 116 | // 117 | // C++'s symbol lookup rule (i.e. Koenig lookup) says that these 118 | // overloads are visible in either the std namespace or the global 119 | // namespace, but not other namespaces, including the testing 120 | // namespace which Google Test's Message class is in. 121 | // 122 | // To allow STL containers (and other types that has a << operator 123 | // defined in the global namespace) to be used in Google Test 124 | // assertions, testing::Message must access the custom << operator 125 | // from the global namespace. With this using declaration, 126 | // overloads of << defined in the global namespace and those 127 | // visible via Koenig lookup are both exposed in this function. 128 | using ::operator <<; 129 | *ss_ << val; 130 | return *this; 131 | } 132 | 133 | // Streams a pointer value to this object. 134 | // 135 | // This function is an overload of the previous one. When you 136 | // stream a pointer to a Message, this definition will be used as it 137 | // is more specialized. (The C++ Standard, section 138 | // [temp.func.order].) If you stream a non-pointer, then the 139 | // previous definition will be used. 140 | // 141 | // The reason for this overload is that streaming a NULL pointer to 142 | // ostream is undefined behavior. Depending on the compiler, you 143 | // may get "0", "(nil)", "(null)", or an access violation. To 144 | // ensure consistent result across compilers, we always treat NULL 145 | // as "(null)". 146 | template 147 | inline Message& operator <<(T* const& pointer) { // NOLINT 148 | if (pointer == nullptr) { 149 | *ss_ << "(null)"; 150 | } else { 151 | *ss_ << pointer; 152 | } 153 | return *this; 154 | } 155 | 156 | // Since the basic IO manipulators are overloaded for both narrow 157 | // and wide streams, we have to provide this specialized definition 158 | // of operator <<, even though its body is the same as the 159 | // templatized version above. Without this definition, streaming 160 | // endl or other basic IO manipulators to Message will confuse the 161 | // compiler. 162 | Message& operator <<(BasicNarrowIoManip val) { 163 | *ss_ << val; 164 | return *this; 165 | } 166 | 167 | // Instead of 1/0, we want to see true/false for bool values. 168 | Message& operator <<(bool b) { 169 | return *this << (b ? "true" : "false"); 170 | } 171 | 172 | // These two overloads allow streaming a wide C string to a Message 173 | // using the UTF-8 encoding. 174 | Message& operator <<(const wchar_t* wide_c_str); 175 | Message& operator <<(wchar_t* wide_c_str); 176 | 177 | #if GTEST_HAS_STD_WSTRING 178 | // Converts the given wide string to a narrow string using the UTF-8 179 | // encoding, and streams the result to this Message object. 180 | Message& operator <<(const ::std::wstring& wstr); 181 | #endif // GTEST_HAS_STD_WSTRING 182 | 183 | // Gets the text streamed to this object so far as an std::string. 184 | // Each '\0' character in the buffer is replaced with "\\0". 185 | // 186 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 187 | std::string GetString() const; 188 | 189 | private: 190 | // We'll hold the text streamed to this object here. 191 | const std::unique_ptr< ::std::stringstream> ss_; 192 | 193 | // We declare (but don't implement) this to prevent the compiler 194 | // from implementing the assignment operator. 195 | void operator=(const Message&); 196 | }; 197 | 198 | // Streams a Message to an ostream. 199 | inline std::ostream& operator <<(std::ostream& os, const Message& sb) { 200 | return os << sb.GetString(); 201 | } 202 | 203 | namespace internal { 204 | 205 | // Converts a streamable value to an std::string. A NULL pointer is 206 | // converted to "(null)". When the input value is a ::string, 207 | // ::std::string, ::wstring, or ::std::wstring object, each NUL 208 | // character in it is replaced with "\\0". 209 | template 210 | std::string StreamableToString(const T& streamable) { 211 | return (Message() << streamable).GetString(); 212 | } 213 | 214 | } // namespace internal 215 | } // namespace testing 216 | 217 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 218 | 219 | #endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 220 | -------------------------------------------------------------------------------- /test/gtest/include/gtest/gtest-test-part.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // GOOGLETEST_CM0001 DO NOT DELETE 31 | 32 | #ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 33 | #define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 34 | 35 | #include 36 | #include 37 | #include "gtest/internal/gtest-internal.h" 38 | #include "gtest/internal/gtest-string.h" 39 | 40 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 41 | /* class A needs to have dll-interface to be used by clients of class B */) 42 | 43 | namespace testing { 44 | 45 | // A copyable object representing the result of a test part (i.e. an 46 | // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). 47 | // 48 | // Don't inherit from TestPartResult as its destructor is not virtual. 49 | class GTEST_API_ TestPartResult { 50 | public: 51 | // The possible outcomes of a test part (i.e. an assertion or an 52 | // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). 53 | enum Type { 54 | kSuccess, // Succeeded. 55 | kNonFatalFailure, // Failed but the test can continue. 56 | kFatalFailure, // Failed and the test should be terminated. 57 | kSkip // Skipped. 58 | }; 59 | 60 | // C'tor. TestPartResult does NOT have a default constructor. 61 | // Always use this constructor (with parameters) to create a 62 | // TestPartResult object. 63 | TestPartResult(Type a_type, const char* a_file_name, int a_line_number, 64 | const char* a_message) 65 | : type_(a_type), 66 | file_name_(a_file_name == nullptr ? "" : a_file_name), 67 | line_number_(a_line_number), 68 | summary_(ExtractSummary(a_message)), 69 | message_(a_message) {} 70 | 71 | // Gets the outcome of the test part. 72 | Type type() const { return type_; } 73 | 74 | // Gets the name of the source file where the test part took place, or 75 | // NULL if it's unknown. 76 | const char* file_name() const { 77 | return file_name_.empty() ? nullptr : file_name_.c_str(); 78 | } 79 | 80 | // Gets the line in the source file where the test part took place, 81 | // or -1 if it's unknown. 82 | int line_number() const { return line_number_; } 83 | 84 | // Gets the summary of the failure message. 85 | const char* summary() const { return summary_.c_str(); } 86 | 87 | // Gets the message associated with the test part. 88 | const char* message() const { return message_.c_str(); } 89 | 90 | // Returns true if and only if the test part was skipped. 91 | bool skipped() const { return type_ == kSkip; } 92 | 93 | // Returns true if and only if the test part passed. 94 | bool passed() const { return type_ == kSuccess; } 95 | 96 | // Returns true if and only if the test part non-fatally failed. 97 | bool nonfatally_failed() const { return type_ == kNonFatalFailure; } 98 | 99 | // Returns true if and only if the test part fatally failed. 100 | bool fatally_failed() const { return type_ == kFatalFailure; } 101 | 102 | // Returns true if and only if the test part failed. 103 | bool failed() const { return fatally_failed() || nonfatally_failed(); } 104 | 105 | private: 106 | Type type_; 107 | 108 | // Gets the summary of the failure message by omitting the stack 109 | // trace in it. 110 | static std::string ExtractSummary(const char* message); 111 | 112 | // The name of the source file where the test part took place, or 113 | // "" if the source file is unknown. 114 | std::string file_name_; 115 | // The line in the source file where the test part took place, or -1 116 | // if the line number is unknown. 117 | int line_number_; 118 | std::string summary_; // The test failure summary. 119 | std::string message_; // The test failure message. 120 | }; 121 | 122 | // Prints a TestPartResult object. 123 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result); 124 | 125 | // An array of TestPartResult objects. 126 | // 127 | // Don't inherit from TestPartResultArray as its destructor is not 128 | // virtual. 129 | class GTEST_API_ TestPartResultArray { 130 | public: 131 | TestPartResultArray() {} 132 | 133 | // Appends the given TestPartResult to the array. 134 | void Append(const TestPartResult& result); 135 | 136 | // Returns the TestPartResult at the given index (0-based). 137 | const TestPartResult& GetTestPartResult(int index) const; 138 | 139 | // Returns the number of TestPartResult objects in the array. 140 | int size() const; 141 | 142 | private: 143 | std::vector array_; 144 | 145 | GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); 146 | }; 147 | 148 | // This interface knows how to report a test part result. 149 | class GTEST_API_ TestPartResultReporterInterface { 150 | public: 151 | virtual ~TestPartResultReporterInterface() {} 152 | 153 | virtual void ReportTestPartResult(const TestPartResult& result) = 0; 154 | }; 155 | 156 | namespace internal { 157 | 158 | // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a 159 | // statement generates new fatal failures. To do so it registers itself as the 160 | // current test part result reporter. Besides checking if fatal failures were 161 | // reported, it only delegates the reporting to the former result reporter. 162 | // The original result reporter is restored in the destructor. 163 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 164 | class GTEST_API_ HasNewFatalFailureHelper 165 | : public TestPartResultReporterInterface { 166 | public: 167 | HasNewFatalFailureHelper(); 168 | ~HasNewFatalFailureHelper() override; 169 | void ReportTestPartResult(const TestPartResult& result) override; 170 | bool has_new_fatal_failure() const { return has_new_fatal_failure_; } 171 | private: 172 | bool has_new_fatal_failure_; 173 | TestPartResultReporterInterface* original_reporter_; 174 | 175 | GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); 176 | }; 177 | 178 | } // namespace internal 179 | 180 | } // namespace testing 181 | 182 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 183 | 184 | #endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 185 | -------------------------------------------------------------------------------- /test/gtest/include/gtest/gtest_prod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // Google C++ Testing and Mocking Framework definitions useful in production code. 32 | // GOOGLETEST_CM0003 DO NOT DELETE 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 35 | #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 36 | 37 | // When you need to test the private or protected members of a class, 38 | // use the FRIEND_TEST macro to declare your tests as friends of the 39 | // class. For example: 40 | // 41 | // class MyClass { 42 | // private: 43 | // void PrivateMethod(); 44 | // FRIEND_TEST(MyClassTest, PrivateMethodWorks); 45 | // }; 46 | // 47 | // class MyClassTest : public testing::Test { 48 | // // ... 49 | // }; 50 | // 51 | // TEST_F(MyClassTest, PrivateMethodWorks) { 52 | // // Can call MyClass::PrivateMethod() here. 53 | // } 54 | // 55 | // Note: The test class must be in the same namespace as the class being tested. 56 | // For example, putting MyClassTest in an anonymous namespace will not work. 57 | 58 | #define FRIEND_TEST(test_case_name, test_name)\ 59 | friend class test_case_name##_##test_name##_Test 60 | 61 | #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 62 | -------------------------------------------------------------------------------- /test/gtest/include/gtest/internal/custom/README.md: -------------------------------------------------------------------------------- 1 | # Customization Points 2 | 3 | The custom directory is an injection point for custom user configurations. 4 | 5 | ## Header `gtest.h` 6 | 7 | ### The following macros can be defined: 8 | 9 | * `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of 10 | `OsStackTraceGetterInterface`. 11 | * `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See 12 | `testing::TempDir` for semantics and signature. 13 | 14 | ## Header `gtest-port.h` 15 | 16 | The following macros can be defined: 17 | 18 | ### Flag related macros: 19 | 20 | * `GTEST_FLAG(flag_name)` 21 | * `GTEST_USE_OWN_FLAGFILE_FLAG_` - Define to 0 when the system provides its 22 | own flagfile flag parsing. 23 | * `GTEST_DECLARE_bool_(name)` 24 | * `GTEST_DECLARE_int32_(name)` 25 | * `GTEST_DECLARE_string_(name)` 26 | * `GTEST_DEFINE_bool_(name, default_val, doc)` 27 | * `GTEST_DEFINE_int32_(name, default_val, doc)` 28 | * `GTEST_DEFINE_string_(name, default_val, doc)` 29 | 30 | ### Logging: 31 | 32 | * `GTEST_LOG_(severity)` 33 | * `GTEST_CHECK_(condition)` 34 | * Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too. 35 | 36 | ### Threading: 37 | 38 | * `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided. 39 | * `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal` 40 | are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)` 41 | and `GTEST_DEFINE_STATIC_MUTEX_(mutex)` 42 | * `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)` 43 | * `GTEST_LOCK_EXCLUDED_(locks)` 44 | 45 | ### Underlying library support features 46 | 47 | * `GTEST_HAS_CXXABI_H_` 48 | 49 | ### Exporting API symbols: 50 | 51 | * `GTEST_API_` - Specifier for exported symbols. 52 | 53 | ## Header `gtest-printers.h` 54 | 55 | * See documentation at `gtest/gtest-printers.h` for details on how to define a 56 | custom printer. 57 | -------------------------------------------------------------------------------- /test/gtest/include/gtest/internal/custom/gtest-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. See README for details 31 | // 32 | // ** Custom implementation starts here ** 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 35 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 36 | 37 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 38 | -------------------------------------------------------------------------------- /test/gtest/include/gtest/internal/custom/gtest-printers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // This file provides an injection point for custom printers in a local 31 | // installation of gTest. 32 | // It will be included from gtest-printers.h and the overrides in this file 33 | // will be visible to everyone. 34 | // 35 | // Injection point for custom user configurations. See README for details 36 | // 37 | // ** Custom implementation starts here ** 38 | 39 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 40 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 41 | 42 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 43 | -------------------------------------------------------------------------------- /test/gtest/include/gtest/internal/custom/gtest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. See README for details 31 | // 32 | // ** Custom implementation starts here ** 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 35 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 36 | 37 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 38 | -------------------------------------------------------------------------------- /test/gtest/include/gtest/internal/gtest-port-arch.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This header file defines the GTEST_OS_* macro. 33 | // It is separate from gtest-port.h so that custom/gtest-port.h can include it. 34 | 35 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 36 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 37 | 38 | // Determines the platform on which Google Test is compiled. 39 | #ifdef __CYGWIN__ 40 | # define GTEST_OS_CYGWIN 1 41 | # elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__) 42 | # define GTEST_OS_WINDOWS_MINGW 1 43 | # define GTEST_OS_WINDOWS 1 44 | #elif defined _WIN32 45 | # define GTEST_OS_WINDOWS 1 46 | # ifdef _WIN32_WCE 47 | # define GTEST_OS_WINDOWS_MOBILE 1 48 | # elif defined(WINAPI_FAMILY) 49 | # include 50 | # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) 51 | # define GTEST_OS_WINDOWS_DESKTOP 1 52 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) 53 | # define GTEST_OS_WINDOWS_PHONE 1 54 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 55 | # define GTEST_OS_WINDOWS_RT 1 56 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) 57 | # define GTEST_OS_WINDOWS_PHONE 1 58 | # define GTEST_OS_WINDOWS_TV_TITLE 1 59 | # else 60 | // WINAPI_FAMILY defined but no known partition matched. 61 | // Default to desktop. 62 | # define GTEST_OS_WINDOWS_DESKTOP 1 63 | # endif 64 | # else 65 | # define GTEST_OS_WINDOWS_DESKTOP 1 66 | # endif // _WIN32_WCE 67 | #elif defined __OS2__ 68 | # define GTEST_OS_OS2 1 69 | #elif defined __APPLE__ 70 | # define GTEST_OS_MAC 1 71 | # include 72 | # if TARGET_OS_IPHONE 73 | # define GTEST_OS_IOS 1 74 | # endif 75 | #elif defined __DragonFly__ 76 | # define GTEST_OS_DRAGONFLY 1 77 | #elif defined __FreeBSD__ 78 | # define GTEST_OS_FREEBSD 1 79 | #elif defined __Fuchsia__ 80 | # define GTEST_OS_FUCHSIA 1 81 | #elif defined(__GLIBC__) && defined(__FreeBSD_kernel__) 82 | # define GTEST_OS_GNU_KFREEBSD 1 83 | #elif defined __linux__ 84 | # define GTEST_OS_LINUX 1 85 | # if defined __ANDROID__ 86 | # define GTEST_OS_LINUX_ANDROID 1 87 | # endif 88 | #elif defined __MVS__ 89 | # define GTEST_OS_ZOS 1 90 | #elif defined(__sun) && defined(__SVR4) 91 | # define GTEST_OS_SOLARIS 1 92 | #elif defined(_AIX) 93 | # define GTEST_OS_AIX 1 94 | #elif defined(__hpux) 95 | # define GTEST_OS_HPUX 1 96 | #elif defined __native_client__ 97 | # define GTEST_OS_NACL 1 98 | #elif defined __NetBSD__ 99 | # define GTEST_OS_NETBSD 1 100 | #elif defined __OpenBSD__ 101 | # define GTEST_OS_OPENBSD 1 102 | #elif defined __QNX__ 103 | # define GTEST_OS_QNX 1 104 | #elif defined(__HAIKU__) 105 | #define GTEST_OS_HAIKU 1 106 | #elif defined ESP8266 107 | #define GTEST_OS_ESP8266 1 108 | #elif defined ESP32 109 | #define GTEST_OS_ESP32 1 110 | #endif // __CYGWIN__ 111 | 112 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 113 | -------------------------------------------------------------------------------- /test/gtest/include/gtest/internal/gtest-string.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This header file declares the String class and functions used internally by 33 | // Google Test. They are subject to change without notice. They should not used 34 | // by code external to Google Test. 35 | // 36 | // This header file is #included by gtest-internal.h. 37 | // It should not be #included by other files. 38 | 39 | // GOOGLETEST_CM0001 DO NOT DELETE 40 | 41 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 42 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 43 | 44 | #ifdef __BORLANDC__ 45 | // string.h is not guaranteed to provide strcpy on C++ Builder. 46 | # include 47 | #endif 48 | 49 | #include 50 | #include 51 | #include 52 | 53 | #include "gtest/internal/gtest-port.h" 54 | 55 | namespace testing { 56 | namespace internal { 57 | 58 | // String - an abstract class holding static string utilities. 59 | class GTEST_API_ String { 60 | public: 61 | // Static utility methods 62 | 63 | // Clones a 0-terminated C string, allocating memory using new. The 64 | // caller is responsible for deleting the return value using 65 | // delete[]. Returns the cloned string, or NULL if the input is 66 | // NULL. 67 | // 68 | // This is different from strdup() in string.h, which allocates 69 | // memory using malloc(). 70 | static const char* CloneCString(const char* c_str); 71 | 72 | #if GTEST_OS_WINDOWS_MOBILE 73 | // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be 74 | // able to pass strings to Win32 APIs on CE we need to convert them 75 | // to 'Unicode', UTF-16. 76 | 77 | // Creates a UTF-16 wide string from the given ANSI string, allocating 78 | // memory using new. The caller is responsible for deleting the return 79 | // value using delete[]. Returns the wide string, or NULL if the 80 | // input is NULL. 81 | // 82 | // The wide string is created using the ANSI codepage (CP_ACP) to 83 | // match the behaviour of the ANSI versions of Win32 calls and the 84 | // C runtime. 85 | static LPCWSTR AnsiToUtf16(const char* c_str); 86 | 87 | // Creates an ANSI string from the given wide string, allocating 88 | // memory using new. The caller is responsible for deleting the return 89 | // value using delete[]. Returns the ANSI string, or NULL if the 90 | // input is NULL. 91 | // 92 | // The returned string is created using the ANSI codepage (CP_ACP) to 93 | // match the behaviour of the ANSI versions of Win32 calls and the 94 | // C runtime. 95 | static const char* Utf16ToAnsi(LPCWSTR utf16_str); 96 | #endif 97 | 98 | // Compares two C strings. Returns true if and only if they have the same 99 | // content. 100 | // 101 | // Unlike strcmp(), this function can handle NULL argument(s). A 102 | // NULL C string is considered different to any non-NULL C string, 103 | // including the empty string. 104 | static bool CStringEquals(const char* lhs, const char* rhs); 105 | 106 | // Converts a wide C string to a String using the UTF-8 encoding. 107 | // NULL will be converted to "(null)". If an error occurred during 108 | // the conversion, "(failed to convert from wide string)" is 109 | // returned. 110 | static std::string ShowWideCString(const wchar_t* wide_c_str); 111 | 112 | // Compares two wide C strings. Returns true if and only if they have the 113 | // same content. 114 | // 115 | // Unlike wcscmp(), this function can handle NULL argument(s). A 116 | // NULL C string is considered different to any non-NULL C string, 117 | // including the empty string. 118 | static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); 119 | 120 | // Compares two C strings, ignoring case. Returns true if and only if 121 | // they have the same content. 122 | // 123 | // Unlike strcasecmp(), this function can handle NULL argument(s). 124 | // A NULL C string is considered different to any non-NULL C string, 125 | // including the empty string. 126 | static bool CaseInsensitiveCStringEquals(const char* lhs, 127 | const char* rhs); 128 | 129 | // Compares two wide C strings, ignoring case. Returns true if and only if 130 | // they have the same content. 131 | // 132 | // Unlike wcscasecmp(), this function can handle NULL argument(s). 133 | // A NULL C string is considered different to any non-NULL wide C string, 134 | // including the empty string. 135 | // NB: The implementations on different platforms slightly differ. 136 | // On windows, this method uses _wcsicmp which compares according to LC_CTYPE 137 | // environment variable. On GNU platform this method uses wcscasecmp 138 | // which compares according to LC_CTYPE category of the current locale. 139 | // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the 140 | // current locale. 141 | static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, 142 | const wchar_t* rhs); 143 | 144 | // Returns true if and only if the given string ends with the given suffix, 145 | // ignoring case. Any string is considered to end with an empty suffix. 146 | static bool EndsWithCaseInsensitive( 147 | const std::string& str, const std::string& suffix); 148 | 149 | // Formats an int value as "%02d". 150 | static std::string FormatIntWidth2(int value); // "%02d" for width == 2 151 | 152 | // Formats an int value to given width with leading zeros. 153 | static std::string FormatIntWidthN(int value, int width); 154 | 155 | // Formats an int value as "%X". 156 | static std::string FormatHexInt(int value); 157 | 158 | // Formats an int value as "%X". 159 | static std::string FormatHexUInt32(uint32_t value); 160 | 161 | // Formats a byte as "%02X". 162 | static std::string FormatByte(unsigned char value); 163 | 164 | private: 165 | String(); // Not meant to be instantiated. 166 | }; // class String 167 | 168 | // Gets the content of the stringstream's buffer as an std::string. Each '\0' 169 | // character in the buffer is replaced with "\\0". 170 | GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); 171 | 172 | } // namespace internal 173 | } // namespace testing 174 | 175 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 176 | -------------------------------------------------------------------------------- /test/gtest/include/gtest/internal/gtest-type-util.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Type utilities needed for implementing typed and type-parameterized 31 | // tests. 32 | 33 | // GOOGLETEST_CM0001 DO NOT DELETE 34 | 35 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 36 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 37 | 38 | #include "gtest/internal/gtest-port.h" 39 | 40 | // #ifdef __GNUC__ is too general here. It is possible to use gcc without using 41 | // libstdc++ (which is where cxxabi.h comes from). 42 | # if GTEST_HAS_CXXABI_H_ 43 | # include 44 | # elif defined(__HP_aCC) 45 | # include 46 | # endif // GTEST_HASH_CXXABI_H_ 47 | 48 | namespace testing { 49 | namespace internal { 50 | 51 | // Canonicalizes a given name with respect to the Standard C++ Library. 52 | // This handles removing the inline namespace within `std` that is 53 | // used by various standard libraries (e.g., `std::__1`). Names outside 54 | // of namespace std are returned unmodified. 55 | inline std::string CanonicalizeForStdLibVersioning(std::string s) { 56 | static const char prefix[] = "std::__"; 57 | if (s.compare(0, strlen(prefix), prefix) == 0) { 58 | std::string::size_type end = s.find("::", strlen(prefix)); 59 | if (end != s.npos) { 60 | // Erase everything between the initial `std` and the second `::`. 61 | s.erase(strlen("std"), end - strlen("std")); 62 | } 63 | } 64 | return s; 65 | } 66 | 67 | #if GTEST_HAS_RTTI 68 | // GetTypeName(const std::type_info&) returns a human-readable name of type T. 69 | inline std::string GetTypeName(const std::type_info& type) { 70 | const char* const name = type.name(); 71 | #if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) 72 | int status = 0; 73 | // gcc's implementation of typeid(T).name() mangles the type name, 74 | // so we have to demangle it. 75 | #if GTEST_HAS_CXXABI_H_ 76 | using abi::__cxa_demangle; 77 | #endif // GTEST_HAS_CXXABI_H_ 78 | char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status); 79 | const std::string name_str(status == 0 ? readable_name : name); 80 | free(readable_name); 81 | return CanonicalizeForStdLibVersioning(name_str); 82 | #else 83 | return name; 84 | #endif // GTEST_HAS_CXXABI_H_ || __HP_aCC 85 | } 86 | #endif // GTEST_HAS_RTTI 87 | 88 | // GetTypeName() returns a human-readable name of type T if and only if 89 | // RTTI is enabled, otherwise it returns a dummy type name. 90 | // NB: This function is also used in Google Mock, so don't move it inside of 91 | // the typed-test-only section below. 92 | template 93 | std::string GetTypeName() { 94 | #if GTEST_HAS_RTTI 95 | return GetTypeName(typeid(T)); 96 | #else 97 | return ""; 98 | #endif // GTEST_HAS_RTTI 99 | } 100 | 101 | // A unique type indicating an empty node 102 | struct None {}; 103 | 104 | # define GTEST_TEMPLATE_ template class 105 | 106 | // The template "selector" struct TemplateSel is used to 107 | // represent Tmpl, which must be a class template with one type 108 | // parameter, as a type. TemplateSel::Bind::type is defined 109 | // as the type Tmpl. This allows us to actually instantiate the 110 | // template "selected" by TemplateSel. 111 | // 112 | // This trick is necessary for simulating typedef for class templates, 113 | // which C++ doesn't support directly. 114 | template 115 | struct TemplateSel { 116 | template 117 | struct Bind { 118 | typedef Tmpl type; 119 | }; 120 | }; 121 | 122 | # define GTEST_BIND_(TmplSel, T) \ 123 | TmplSel::template Bind::type 124 | 125 | template 126 | struct Templates { 127 | using Head = TemplateSel; 128 | using Tail = Templates; 129 | }; 130 | 131 | template 132 | struct Templates { 133 | using Head = TemplateSel; 134 | using Tail = None; 135 | }; 136 | 137 | // Tuple-like type lists 138 | template 139 | struct Types { 140 | using Head = Head_; 141 | using Tail = Types; 142 | }; 143 | 144 | template 145 | struct Types { 146 | using Head = Head_; 147 | using Tail = None; 148 | }; 149 | 150 | // Helper metafunctions to tell apart a single type from types 151 | // generated by ::testing::Types 152 | template 153 | struct ProxyTypeList { 154 | using type = Types; 155 | }; 156 | 157 | template 158 | struct is_proxy_type_list : std::false_type {}; 159 | 160 | template 161 | struct is_proxy_type_list> : std::true_type {}; 162 | 163 | // Generator which conditionally creates type lists. 164 | // It recognizes if a requested type list should be created 165 | // and prevents creating a new type list nested within another one. 166 | template 167 | struct GenerateTypeList { 168 | private: 169 | using proxy = typename std::conditional::value, T, 170 | ProxyTypeList>::type; 171 | 172 | public: 173 | using type = typename proxy::type; 174 | }; 175 | 176 | } // namespace internal 177 | 178 | template 179 | using Types = internal::ProxyTypeList; 180 | 181 | } // namespace testing 182 | 183 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 184 | -------------------------------------------------------------------------------- /test/gtest/src/gtest-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // Google C++ Testing and Mocking Framework (Google Test) 32 | // 33 | // Sometimes it's desirable to build Google Test by compiling a single file. 34 | // This file serves this purpose. 35 | 36 | // This line ensures that gtest.h can be compiled on its own, even 37 | // when it's fused. 38 | #include "gtest/gtest.h" 39 | 40 | // The following lines pull in the real gtest *.cc files. 41 | #include "src/gtest.cc" 42 | #include "src/gtest-death-test.cc" 43 | #include "src/gtest-filepath.cc" 44 | #include "src/gtest-matchers.cc" 45 | #include "src/gtest-port.cc" 46 | #include "src/gtest-printers.cc" 47 | #include "src/gtest-test-part.cc" 48 | #include "src/gtest-typed-test.cc" 49 | -------------------------------------------------------------------------------- /test/gtest/src/gtest-matchers.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This file implements just enough of the matcher interface to allow 33 | // EXPECT_DEATH and friends to accept a matcher argument. 34 | 35 | #include "gtest/internal/gtest-internal.h" 36 | #include "gtest/internal/gtest-port.h" 37 | #include "gtest/gtest-matchers.h" 38 | 39 | #include 40 | 41 | namespace testing { 42 | 43 | // Constructs a matcher that matches a const std::string& whose value is 44 | // equal to s. 45 | Matcher::Matcher(const std::string& s) { *this = Eq(s); } 46 | 47 | // Constructs a matcher that matches a const std::string& whose value is 48 | // equal to s. 49 | Matcher::Matcher(const char* s) { 50 | *this = Eq(std::string(s)); 51 | } 52 | 53 | // Constructs a matcher that matches a std::string whose value is equal to 54 | // s. 55 | Matcher::Matcher(const std::string& s) { *this = Eq(s); } 56 | 57 | // Constructs a matcher that matches a std::string whose value is equal to 58 | // s. 59 | Matcher::Matcher(const char* s) { *this = Eq(std::string(s)); } 60 | 61 | #if GTEST_INTERNAL_HAS_STRING_VIEW 62 | // Constructs a matcher that matches a const StringView& whose value is 63 | // equal to s. 64 | Matcher::Matcher(const std::string& s) { 65 | *this = Eq(s); 66 | } 67 | 68 | // Constructs a matcher that matches a const StringView& whose value is 69 | // equal to s. 70 | Matcher::Matcher(const char* s) { 71 | *this = Eq(std::string(s)); 72 | } 73 | 74 | // Constructs a matcher that matches a const StringView& whose value is 75 | // equal to s. 76 | Matcher::Matcher(internal::StringView s) { 77 | *this = Eq(std::string(s)); 78 | } 79 | 80 | // Constructs a matcher that matches a StringView whose value is equal to 81 | // s. 82 | Matcher::Matcher(const std::string& s) { *this = Eq(s); } 83 | 84 | // Constructs a matcher that matches a StringView whose value is equal to 85 | // s. 86 | Matcher::Matcher(const char* s) { 87 | *this = Eq(std::string(s)); 88 | } 89 | 90 | // Constructs a matcher that matches a StringView whose value is equal to 91 | // s. 92 | Matcher::Matcher(internal::StringView s) { 93 | *this = Eq(std::string(s)); 94 | } 95 | #endif // GTEST_INTERNAL_HAS_STRING_VIEW 96 | 97 | } // namespace testing 98 | -------------------------------------------------------------------------------- /test/gtest/src/gtest-test-part.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // The Google C++ Testing and Mocking Framework (Google Test) 32 | 33 | #include "gtest/gtest-test-part.h" 34 | 35 | #include "gtest/internal/gtest-port.h" 36 | #include "src/gtest-internal-inl.h" 37 | 38 | namespace testing { 39 | 40 | using internal::GetUnitTestImpl; 41 | 42 | // Gets the summary of the failure message by omitting the stack trace 43 | // in it. 44 | std::string TestPartResult::ExtractSummary(const char* message) { 45 | const char* const stack_trace = strstr(message, internal::kStackTraceMarker); 46 | return stack_trace == nullptr ? message : std::string(message, stack_trace); 47 | } 48 | 49 | // Prints a TestPartResult object. 50 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { 51 | return os << internal::FormatFileLocation(result.file_name(), 52 | result.line_number()) 53 | << " " 54 | << (result.type() == TestPartResult::kSuccess 55 | ? "Success" 56 | : result.type() == TestPartResult::kSkip 57 | ? "Skipped" 58 | : result.type() == TestPartResult::kFatalFailure 59 | ? "Fatal failure" 60 | : "Non-fatal failure") 61 | << ":\n" 62 | << result.message() << std::endl; 63 | } 64 | 65 | // Appends a TestPartResult to the array. 66 | void TestPartResultArray::Append(const TestPartResult& result) { 67 | array_.push_back(result); 68 | } 69 | 70 | // Returns the TestPartResult at the given index (0-based). 71 | const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { 72 | if (index < 0 || index >= size()) { 73 | printf("\nInvalid index (%d) into TestPartResultArray.\n", index); 74 | internal::posix::Abort(); 75 | } 76 | 77 | return array_[static_cast(index)]; 78 | } 79 | 80 | // Returns the number of TestPartResult objects in the array. 81 | int TestPartResultArray::size() const { 82 | return static_cast(array_.size()); 83 | } 84 | 85 | namespace internal { 86 | 87 | HasNewFatalFailureHelper::HasNewFatalFailureHelper() 88 | : has_new_fatal_failure_(false), 89 | original_reporter_(GetUnitTestImpl()-> 90 | GetTestPartResultReporterForCurrentThread()) { 91 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); 92 | } 93 | 94 | HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { 95 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( 96 | original_reporter_); 97 | } 98 | 99 | void HasNewFatalFailureHelper::ReportTestPartResult( 100 | const TestPartResult& result) { 101 | if (result.fatally_failed()) 102 | has_new_fatal_failure_ = true; 103 | original_reporter_->ReportTestPartResult(result); 104 | } 105 | 106 | } // namespace internal 107 | 108 | } // namespace testing 109 | -------------------------------------------------------------------------------- /test/gtest/src/gtest-typed-test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | #include "gtest/gtest-typed-test.h" 32 | 33 | #include "gtest/gtest.h" 34 | 35 | namespace testing { 36 | namespace internal { 37 | 38 | // Skips to the first non-space char in str. Returns an empty string if str 39 | // contains only whitespace characters. 40 | static const char* SkipSpaces(const char* str) { 41 | while (IsSpace(*str)) 42 | str++; 43 | return str; 44 | } 45 | 46 | static std::vector SplitIntoTestNames(const char* src) { 47 | std::vector name_vec; 48 | src = SkipSpaces(src); 49 | for (; src != nullptr; src = SkipComma(src)) { 50 | name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); 51 | } 52 | return name_vec; 53 | } 54 | 55 | // Verifies that registered_tests match the test names in 56 | // registered_tests_; returns registered_tests if successful, or 57 | // aborts the program otherwise. 58 | const char* TypedTestSuitePState::VerifyRegisteredTestNames( 59 | const char* test_suite_name, const char* file, int line, 60 | const char* registered_tests) { 61 | RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line)); 62 | 63 | typedef RegisteredTestsMap::const_iterator RegisteredTestIter; 64 | registered_ = true; 65 | 66 | std::vector name_vec = SplitIntoTestNames(registered_tests); 67 | 68 | Message errors; 69 | 70 | std::set tests; 71 | for (std::vector::const_iterator name_it = name_vec.begin(); 72 | name_it != name_vec.end(); ++name_it) { 73 | const std::string& name = *name_it; 74 | if (tests.count(name) != 0) { 75 | errors << "Test " << name << " is listed more than once.\n"; 76 | continue; 77 | } 78 | 79 | if (registered_tests_.count(name) != 0) { 80 | tests.insert(name); 81 | } else { 82 | errors << "No test named " << name 83 | << " can be found in this test suite.\n"; 84 | } 85 | } 86 | 87 | for (RegisteredTestIter it = registered_tests_.begin(); 88 | it != registered_tests_.end(); 89 | ++it) { 90 | if (tests.count(it->first) == 0) { 91 | errors << "You forgot to list test " << it->first << ".\n"; 92 | } 93 | } 94 | 95 | const std::string& errors_str = errors.GetString(); 96 | if (errors_str != "") { 97 | fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), 98 | errors_str.c_str()); 99 | fflush(stderr); 100 | posix::Abort(); 101 | } 102 | 103 | return registered_tests; 104 | } 105 | 106 | } // namespace internal 107 | } // namespace testing 108 | -------------------------------------------------------------------------------- /test/gtest/src/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | #include "gtest/gtest.h" 32 | 33 | #if GTEST_OS_ESP8266 || GTEST_OS_ESP32 34 | #if GTEST_OS_ESP8266 35 | extern "C" { 36 | #endif 37 | void setup() { 38 | testing::InitGoogleTest(); 39 | } 40 | 41 | void loop() { RUN_ALL_TESTS(); } 42 | 43 | #if GTEST_OS_ESP8266 44 | } 45 | #endif 46 | 47 | #else 48 | 49 | GTEST_API_ int main(int argc, char **argv) { 50 | printf("Running main() from %s\n", __FILE__); 51 | testing::InitGoogleTest(&argc, argv); 52 | return RUN_ALL_TESTS(); 53 | } 54 | #endif 55 | -------------------------------------------------------------------------------- /test/main.cpp: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | 3 | int main(int argc, char **argv) { 4 | testing::InitGoogleTest(&argc, argv); 5 | return RUN_ALL_TESTS(); 6 | } 7 | -------------------------------------------------------------------------------- /test/test.cpp: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "url_signature.h" 3 | 4 | int add(int a, int b) { 5 | return a + b; 6 | } 7 | 8 | TEST(SuiteName, TestName1) { 9 | int expected = 3; 10 | int actual = add(1, 2); 11 | ASSERT_EQ(expected, actual); 12 | } 13 | 14 | TEST(SuiteName, TestName2) { 15 | std::string url = "https://example.com?key2=value2&key3=value3&key1=VALUE1"; 16 | std::string expected = "https://example.com?key2=value2&key3=value3&key1=VALUE1&sign=5779f1cd4693e8b3c5981d37d20aa331"; 17 | std::string actual = SignatureUrl(url); 18 | ASSERT_EQ(expected, actual); 19 | } -------------------------------------------------------------------------------- /third_party/cxxurl/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10.2) 2 | project(cxxurl) 3 | # 定义需要参与编译的源文件 4 | aux_source_directory(./src source) 5 | # 把源码添加进来参与编译 6 | add_library(${PROJECT_NAME} ${source}) 7 | # 定义需要暴露的头文件 8 | target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include) -------------------------------------------------------------------------------- /third_party/cxxurl/include/cxxurl/string.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STRING_H 2 | #define STRING_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef ANDROID_PLATFORM 8 | namespace std 9 | { 10 | template < typename T > std::string to_string( const T& n ) 11 | { 12 | std::ostringstream stm ; 13 | stm << n ; 14 | return stm.str() ; 15 | } 16 | } 17 | #endif 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /third_party/cxxurl/include/cxxurl/url.hpp: -------------------------------------------------------------------------------- 1 | #ifndef URL_HPP 2 | #define URL_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "string.hpp" 11 | 12 | class Url { 13 | public: 14 | // Exception thut may be thrown when decoding an URL or an assigning value 15 | class parse_error: public std::invalid_argument { 16 | public: 17 | parse_error(const std::string &reason) : std::invalid_argument(reason) {} 18 | }; 19 | 20 | // Exception that may be thrown when building an URL 21 | class build_error: public std::runtime_error { 22 | public: 23 | build_error(const std::string &reason) : std::runtime_error(reason) {} 24 | }; 25 | 26 | // Default constructor 27 | Url() : m_parse(true),m_built(true),m_ip_v(-1) {} 28 | 29 | // Copy initializer constructor 30 | Url(const Url &url) : m_ip_v(-1) {assign(url);} 31 | 32 | // Move constructor 33 | Url(Url&& url) : m_ip_v(-1) {assign(std::move(url));} 34 | 35 | // Construct Url with the given string 36 | Url(const std::string &url_str) : m_url(url_str),m_parse(false),m_built(false),m_ip_v(-1) {} 37 | 38 | // Assign the given URL string 39 | Url &operator=(const std::string &url_str) {return str(url_str);} 40 | 41 | // Assign the given Url object 42 | Url &operator=(const Url &url) {assign(url); return *this;} 43 | 44 | // Move the given Url object 45 | Url &operator=(Url&& url) {assign(std::move(url)); return *this;} 46 | 47 | // Clear the Url object 48 | Url &clear(); 49 | 50 | // Build Url if needed and return it as string 51 | std::string str() const {if(!m_built) build_url(); return m_url;} 52 | 53 | // Set the Url to the given string. All fields are overwritten 54 | Url& str(const std::string &url_str) {m_url=url_str; m_built=m_parse=false; return *this;} 55 | 56 | // Get scheme 57 | const std::string& scheme() const {lazy_parse(); return m_scheme;} 58 | 59 | // Set scheme 60 | Url &scheme(const std::string& s); 61 | 62 | // Get user info 63 | const std::string& user_info() const {lazy_parse(); return m_user;} 64 | 65 | // Set user info 66 | Url &user_info(const std::string& s); 67 | 68 | // Get host 69 | const std::string& host() const {lazy_parse(); return m_host;} 70 | 71 | // Set host 72 | Url &host(const std::string& h, uint8_t ip_v=0); 73 | 74 | // Get host IP version: 0=name, 4=IPv4, 6=IPv6, -1=undefined 75 | std::int8_t ip_version() const {lazy_parse(); return m_ip_v;} 76 | 77 | // Get port 78 | const std::string& port() const {lazy_parse(); return m_port;} 79 | 80 | // Set Port given as string 81 | Url &port(const std::string& str); 82 | 83 | // Set port given as a 16bit unsigned integer 84 | Url &port(std::uint16_t num) {return port(std::to_string(num));} 85 | 86 | // Get path 87 | const std::string& path() const {lazy_parse(); return m_path;} 88 | 89 | // Set path 90 | Url &path(const std::string& str); 91 | 92 | class KeyVal { 93 | public: 94 | // Default constructor 95 | KeyVal() {} 96 | 97 | // Construct with provided Key and Value strings 98 | KeyVal(const std::string &key, const std::string &val) : m_key(key),m_val(val) {} 99 | 100 | // Construct with provided Key string, val will be empty 101 | KeyVal(const std::string &key) : m_key(key) {} 102 | 103 | // Equality test operator 104 | bool operator==(const KeyVal &q) const {return m_key==q.m_key&&m_val==q.m_val;} 105 | 106 | // Swap this with q 107 | void swap(KeyVal& q) {std::swap(m_key,q.m_key); std::swap(m_val,q.m_val);} 108 | 109 | // Get key 110 | const std::string& key() const {return m_key;} 111 | 112 | // Set key 113 | void key(const std::string &k) {m_key=k;} 114 | 115 | // Get value 116 | const std::string& val() const {return m_val;} 117 | 118 | // Set value 119 | void val(const std::string &v) {m_val=v;} 120 | 121 | // Output key value pair 122 | friend std::ostream& operator<<(std::ostream &o, const KeyVal &kv) 123 | {o<<" "; return o;} 124 | 125 | private: 126 | std::string m_key; 127 | std::string m_val; 128 | }; 129 | 130 | // Define Query as vector of Key Value pairs 131 | typedef std::vector Query; 132 | 133 | // Get a reference to the query vector for read only access 134 | const Query& query() const {lazy_parse(); return m_query;} 135 | 136 | // Get a reference to a specific Key Value pair in the query vector for read only access 137 | const KeyVal& query(size_t i) const { 138 | lazy_parse(); 139 | if (i>=m_query.size()) 140 | throw std::out_of_range("Invalid Url query index ("+std::to_string(i)+")"); 141 | return m_query[i]; 142 | } 143 | 144 | // Get a reference to the query vector for a writable access 145 | Query& set_query() {lazy_parse(); m_built=false; return m_query;} 146 | 147 | // Get a reference to specific Key Value pair in the query vector for a writable access 148 | KeyVal& set_query(size_t i) { 149 | lazy_parse(); 150 | if (i>=m_query.size()) 151 | throw std::out_of_range("Invalid Url query index ("+std::to_string(i)+")"); 152 | m_built=false; 153 | return m_query[i]; 154 | } 155 | 156 | // Set the query vector to the Query vector q 157 | Url &set_query(const Query &q) 158 | {lazy_parse(); if (q != m_query) {m_query=q; m_built=false;} return *this;} 159 | 160 | // Append KeyVal kv to the query 161 | Url &add_query(const KeyVal &kv) 162 | {lazy_parse(); m_built=false; m_query.push_back(kv); return *this;} 163 | 164 | // Append key val pair to the query 165 | Url &add_query(const std::string &key, const std::string &val) 166 | {lazy_parse(); m_built=false; m_query.emplace_back(key,val); return *this;} 167 | 168 | // Append key with empty val to the query 169 | Url &add_query(const std::string &key) 170 | {lazy_parse(); m_built=false; m_query.emplace_back(key); return *this;} 171 | 172 | // Get the fragment 173 | const std::string& fragment() const {lazy_parse(); return m_fragment;} 174 | 175 | // Set the fragment 176 | Url &fragment(const std::string& f); 177 | 178 | // Output 179 | std::ostream& output(std::ostream &o) const; 180 | 181 | // Output strean operator 182 | friend std::ostream& operator<<(std::ostream &o, const Url &u) {return u.output(o);} 183 | 184 | private: 185 | void assign(const Url &url); 186 | void assign(Url&& url); 187 | void build_url() const; 188 | void lazy_parse() const {if (!m_parse) parse_url();} 189 | void parse_url() const; 190 | 191 | mutable std::string m_scheme; 192 | mutable std::string m_user; 193 | mutable std::string m_host; 194 | mutable std::string m_port; 195 | mutable std::string m_path; 196 | mutable Query m_query; 197 | mutable std::string m_fragment; 198 | mutable std::string m_url; 199 | mutable bool m_parse; 200 | mutable bool m_built; 201 | mutable std::int8_t m_ip_v; 202 | }; 203 | 204 | 205 | 206 | 207 | #endif // URL_HPP 208 | 209 | -------------------------------------------------------------------------------- /third_party/hash/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10.2) 2 | project(hash) 3 | # 定义需要参与编译的源文件 4 | aux_source_directory(./src source) 5 | # 把源码添加进来参与编译 6 | add_library(${PROJECT_NAME} ${source}) 7 | # 定义需要暴露的头文件 8 | target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include) -------------------------------------------------------------------------------- /third_party/hash/include/crc32.h: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // crc32.h 3 | // Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | #pragma once 8 | 9 | //#include "hash.h" 10 | #include 11 | 12 | // define fixed size integer types 13 | #ifdef _MSC_VER 14 | // Windows 15 | typedef unsigned __int8 uint8_t; 16 | typedef unsigned __int32 uint32_t; 17 | #else 18 | // GCC 19 | #include 20 | #endif 21 | 22 | 23 | /// compute CRC32 hash, based on Intel's Slicing-by-8 algorithm 24 | /** Usage: 25 | CRC32 crc32; 26 | std::string myHash = crc32("Hello World"); // std::string 27 | std::string myHash2 = crc32("How are you", 11); // arbitrary data, 11 bytes 28 | 29 | // or in a streaming fashion: 30 | 31 | CRC32 crc32; 32 | while (more data available) 33 | crc32.add(pointer to fresh data, number of new bytes); 34 | std::string myHash3 = crc32.getHash(); 35 | 36 | Note: 37 | You can find code for the faster Slicing-by-16 algorithm on my website, too: 38 | http://create.stephan-brumme.com/crc32/ 39 | Its unrolled version is about twice as fast but its look-up table doubled in size as well. 40 | */ 41 | class CRC32 //: public Hash 42 | { 43 | public: 44 | /// hash is 4 bytes long 45 | enum { HashBytes = 4 }; 46 | 47 | /// same as reset() 48 | CRC32(); 49 | 50 | /// compute CRC32 of a memory block 51 | std::string operator()(const void* data, size_t numBytes); 52 | /// compute CRC32 of a string, excluding final zero 53 | std::string operator()(const std::string& text); 54 | 55 | /// add arbitrary number of bytes 56 | void add(const void* data, size_t numBytes); 57 | 58 | /// return latest hash as 8 hex characters 59 | std::string getHash(); 60 | /// return latest hash as bytes 61 | void getHash(unsigned char buffer[HashBytes]); 62 | 63 | /// restart 64 | void reset(); 65 | 66 | private: 67 | /// hash 68 | uint32_t m_hash; 69 | }; 70 | -------------------------------------------------------------------------------- /third_party/hash/include/hash.h: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // hash.h 3 | // Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | /// abstract base class 12 | class Hash 13 | { 14 | public: 15 | /// compute hash of a memory block 16 | virtual std::string operator()(const void* data, size_t numBytes) = 0; 17 | /// compute hash of a string, excluding final zero 18 | virtual std::string operator()(const std::string& text) = 0; 19 | 20 | /// add arbitrary number of bytes 21 | virtual void add(const void* data, size_t numBytes) = 0; 22 | 23 | /// return latest hash as hex characters 24 | virtual std::string getHash() = 0; 25 | 26 | /// restart 27 | virtual void reset() = 0; 28 | }; 29 | -------------------------------------------------------------------------------- /third_party/hash/include/hmac.h: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // hmac.h 3 | // Copyright (c) 2015 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | #pragma once 8 | 9 | // based on http://tools.ietf.org/html/rfc2104 10 | // see also http://en.wikipedia.org/wiki/Hash-based_message_authentication_code 11 | 12 | /** Usage: 13 | std::string msg = "The quick brown fox jumps over the lazy dog"; 14 | std::string key = "key"; 15 | std::string md5hmac = hmac< MD5 >(msg, key); 16 | std::string sha1hmac = hmac< SHA1 >(msg, key); 17 | std::string sha2hmac = hmac(msg, key); 18 | 19 | Note: 20 | To keep my code simple, HMAC computation currently needs the whole message at once. 21 | This is in contrast to the hashes MD5, SHA1, etc. where an add() method is available 22 | for incremental computation. 23 | You can use any hash for HMAC as long as it provides: 24 | - constant HashMethod::BlockSize (typically 64) 25 | - constant HashMethod::HashBytes (length of hash in bytes, e.g. 20 for SHA1) 26 | - HashMethod::add(buffer, bufferSize) 27 | - HashMethod::getHash(unsigned char buffer[HashMethod::BlockSize]) 28 | */ 29 | 30 | #include 31 | #include // memcpy 32 | 33 | /// compute HMAC hash of data and key using MD5, SHA1 or SHA256 34 | template 35 | std::string hmac(const void* data, size_t numDataBytes, const void* key, size_t numKeyBytes) 36 | { 37 | // initialize key with zeros 38 | unsigned char usedKey[HashMethod::BlockSize] = {0}; 39 | 40 | // adjust length of key: must contain exactly blockSize bytes 41 | if (numKeyBytes <= HashMethod::BlockSize) 42 | { 43 | // copy key 44 | memcpy(usedKey, key, numKeyBytes); 45 | } 46 | else 47 | { 48 | // shorten key: usedKey = hashed(key) 49 | HashMethod keyHasher; 50 | keyHasher.add(key, numKeyBytes); 51 | keyHasher.getHash(usedKey); 52 | } 53 | 54 | // create initial XOR padding 55 | for (size_t i = 0; i < HashMethod::BlockSize; i++) 56 | usedKey[i] ^= 0x36; 57 | 58 | // inside = hash((usedKey ^ 0x36) + data) 59 | unsigned char inside[HashMethod::HashBytes]; 60 | HashMethod insideHasher; 61 | insideHasher.add(usedKey, HashMethod::BlockSize); 62 | insideHasher.add(data, numDataBytes); 63 | insideHasher.getHash(inside); 64 | 65 | // undo usedKey's previous 0x36 XORing and apply a XOR by 0x5C 66 | for (size_t i = 0; i < HashMethod::BlockSize; i++) 67 | usedKey[i] ^= 0x5C ^ 0x36; 68 | 69 | // hash((usedKey ^ 0x5C) + hash((usedKey ^ 0x36) + data)) 70 | HashMethod finalHasher; 71 | finalHasher.add(usedKey, HashMethod::BlockSize); 72 | finalHasher.add(inside, HashMethod::HashBytes); 73 | 74 | return finalHasher.getHash(); 75 | } 76 | 77 | 78 | /// convenience function for std::string 79 | template 80 | std::string hmac(const std::string& data, const std::string& key) 81 | { 82 | return hmac(data.c_str(), data.size(), key.c_str(), key.size()); 83 | } 84 | -------------------------------------------------------------------------------- /third_party/hash/include/keccak.h: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // keccak.h 3 | // Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | #pragma once 8 | 9 | //#include "hash.h" 10 | #include 11 | 12 | // define fixed size integer types 13 | #ifdef _MSC_VER 14 | // Windows 15 | typedef unsigned __int8 uint8_t; 16 | typedef unsigned __int64 uint64_t; 17 | #else 18 | // GCC 19 | #include 20 | #endif 21 | 22 | 23 | /// compute Keccak hash (designated SHA3) 24 | /** Usage: 25 | Keccak keccak; 26 | std::string myHash = keccak("Hello World"); // std::string 27 | std::string myHash2 = keccak("How are you", 11); // arbitrary data, 11 bytes 28 | 29 | // or in a streaming fashion: 30 | 31 | Keccak keccak; 32 | while (more data available) 33 | keccak.add(pointer to fresh data, number of new bytes); 34 | std::string myHash3 = keccak.getHash(); 35 | */ 36 | class Keccak //: public Hash 37 | { 38 | public: 39 | /// algorithm variants 40 | enum Bits { Keccak224 = 224, Keccak256 = 256, Keccak384 = 384, Keccak512 = 512 }; 41 | 42 | /// same as reset() 43 | explicit Keccak(Bits bits = Keccak256); 44 | 45 | /// compute hash of a memory block 46 | std::string operator()(const void* data, size_t numBytes); 47 | /// compute hash of a string, excluding final zero 48 | std::string operator()(const std::string& text); 49 | 50 | /// add arbitrary number of bytes 51 | void add(const void* data, size_t numBytes); 52 | 53 | /// return latest hash as hex characters 54 | std::string getHash(); 55 | 56 | /// restart 57 | void reset(); 58 | 59 | private: 60 | /// process a full block 61 | void processBlock(const void* data); 62 | /// process everything left in the internal buffer 63 | void processBuffer(); 64 | 65 | /// 1600 bits, stored as 25x64 bit, BlockSize is no more than 1152 bits (Keccak224) 66 | enum { StateSize = 1600 / (8 * 8), 67 | MaxBlockSize = 200 - 2 * (224 / 8) }; 68 | 69 | /// hash 70 | uint64_t m_hash[StateSize]; 71 | /// size of processed data in bytes 72 | uint64_t m_numBytes; 73 | /// block size (less or equal to MaxBlockSize) 74 | size_t m_blockSize; 75 | /// valid bytes in m_buffer 76 | size_t m_bufferSize; 77 | /// bytes not processed yet 78 | uint8_t m_buffer[MaxBlockSize]; 79 | /// variant 80 | Bits m_bits; 81 | }; 82 | -------------------------------------------------------------------------------- /third_party/hash/include/md5.h: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // md5.h 3 | // Copyright (c) 2014 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | #pragma once 8 | 9 | //#include "hash.h" 10 | #include 11 | 12 | // define fixed size integer types 13 | #ifdef _MSC_VER 14 | // Windows 15 | typedef unsigned __int8 uint8_t; 16 | typedef unsigned __int32 uint32_t; 17 | typedef unsigned __int64 uint64_t; 18 | #else 19 | // GCC 20 | #include 21 | #endif 22 | 23 | 24 | /// compute MD5 hash 25 | /** Usage: 26 | MD5 md5; 27 | std::string myHash = md5("Hello World"); // std::string 28 | std::string myHash2 = md5("How are you", 11); // arbitrary data, 11 bytes 29 | 30 | // or in a streaming fashion: 31 | 32 | MD5 md5; 33 | while (more data available) 34 | md5.add(pointer to fresh data, number of new bytes); 35 | std::string myHash3 = md5.getHash(); 36 | */ 37 | class MD5 //: public Hash 38 | { 39 | public: 40 | /// split into 64 byte blocks (=> 512 bits), hash is 16 bytes long 41 | enum { BlockSize = 512 / 8, HashBytes = 16 }; 42 | 43 | /// same as reset() 44 | MD5(); 45 | 46 | /// compute MD5 of a memory block 47 | std::string operator()(const void* data, size_t numBytes); 48 | /// compute MD5 of a string, excluding final zero 49 | std::string operator()(const std::string& text); 50 | 51 | /// add arbitrary number of bytes 52 | void add(const void* data, size_t numBytes); 53 | 54 | /// return latest hash as 32 hex characters 55 | std::string getHash(); 56 | /// return latest hash as bytes 57 | void getHash(unsigned char buffer[HashBytes]); 58 | 59 | /// restart 60 | void reset(); 61 | 62 | private: 63 | /// process 64 bytes 64 | void processBlock(const void* data); 65 | /// process everything left in the internal buffer 66 | void processBuffer(); 67 | 68 | /// size of processed data in bytes 69 | uint64_t m_numBytes; 70 | /// valid bytes in m_buffer 71 | size_t m_bufferSize; 72 | /// bytes not processed yet 73 | uint8_t m_buffer[BlockSize]; 74 | 75 | enum { HashValues = HashBytes / 4 }; 76 | /// hash, stored as integers 77 | uint32_t m_hash[HashValues]; 78 | }; 79 | -------------------------------------------------------------------------------- /third_party/hash/include/sha1.h: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // sha1.h 3 | // Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | #pragma once 8 | 9 | //#include "hash.h" 10 | #include 11 | 12 | // define fixed size integer types 13 | #ifdef _MSC_VER 14 | // Windows 15 | typedef unsigned __int8 uint8_t; 16 | typedef unsigned __int32 uint32_t; 17 | typedef unsigned __int64 uint64_t; 18 | #else 19 | // GCC 20 | #include 21 | #endif 22 | 23 | 24 | /// compute SHA1 hash 25 | /** Usage: 26 | SHA1 sha1; 27 | std::string myHash = sha1("Hello World"); // std::string 28 | std::string myHash2 = sha1("How are you", 11); // arbitrary data, 11 bytes 29 | 30 | // or in a streaming fashion: 31 | 32 | SHA1 sha1; 33 | while (more data available) 34 | sha1.add(pointer to fresh data, number of new bytes); 35 | std::string myHash3 = sha1.getHash(); 36 | */ 37 | class SHA1 //: public Hash 38 | { 39 | public: 40 | /// split into 64 byte blocks (=> 512 bits), hash is 20 bytes long 41 | enum { BlockSize = 512 / 8, HashBytes = 20 }; 42 | 43 | /// same as reset() 44 | SHA1(); 45 | 46 | /// compute SHA1 of a memory block 47 | std::string operator()(const void* data, size_t numBytes); 48 | /// compute SHA1 of a string, excluding final zero 49 | std::string operator()(const std::string& text); 50 | 51 | /// add arbitrary number of bytes 52 | void add(const void* data, size_t numBytes); 53 | 54 | /// return latest hash as 40 hex characters 55 | std::string getHash(); 56 | /// return latest hash as bytes 57 | void getHash(unsigned char buffer[HashBytes]); 58 | 59 | /// restart 60 | void reset(); 61 | 62 | private: 63 | /// process 64 bytes 64 | void processBlock(const void* data); 65 | /// process everything left in the internal buffer 66 | void processBuffer(); 67 | 68 | /// size of processed data in bytes 69 | uint64_t m_numBytes; 70 | /// valid bytes in m_buffer 71 | size_t m_bufferSize; 72 | /// bytes not processed yet 73 | uint8_t m_buffer[BlockSize]; 74 | 75 | enum { HashValues = HashBytes / 4 }; 76 | /// hash, stored as integers 77 | uint32_t m_hash[HashValues]; 78 | }; 79 | -------------------------------------------------------------------------------- /third_party/hash/include/sha256.h: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // sha256.h 3 | // Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | #pragma once 8 | 9 | //#include "hash.h" 10 | #include 11 | 12 | // define fixed size integer types 13 | #ifdef _MSC_VER 14 | // Windows 15 | typedef unsigned __int8 uint8_t; 16 | typedef unsigned __int32 uint32_t; 17 | typedef unsigned __int64 uint64_t; 18 | #else 19 | // GCC 20 | #include 21 | #endif 22 | 23 | 24 | /// compute SHA256 hash 25 | /** Usage: 26 | SHA256 sha256; 27 | std::string myHash = sha256("Hello World"); // std::string 28 | std::string myHash2 = sha256("How are you", 11); // arbitrary data, 11 bytes 29 | 30 | // or in a streaming fashion: 31 | 32 | SHA256 sha256; 33 | while (more data available) 34 | sha256.add(pointer to fresh data, number of new bytes); 35 | std::string myHash3 = sha256.getHash(); 36 | */ 37 | class SHA256 //: public Hash 38 | { 39 | public: 40 | /// split into 64 byte blocks (=> 512 bits), hash is 32 bytes long 41 | enum { BlockSize = 512 / 8, HashBytes = 32 }; 42 | 43 | /// same as reset() 44 | SHA256(); 45 | 46 | /// compute SHA256 of a memory block 47 | std::string operator()(const void* data, size_t numBytes); 48 | /// compute SHA256 of a string, excluding final zero 49 | std::string operator()(const std::string& text); 50 | 51 | /// add arbitrary number of bytes 52 | void add(const void* data, size_t numBytes); 53 | 54 | /// return latest hash as 64 hex characters 55 | std::string getHash(); 56 | /// return latest hash as bytes 57 | void getHash(unsigned char buffer[HashBytes]); 58 | 59 | /// restart 60 | void reset(); 61 | 62 | private: 63 | /// process 64 bytes 64 | void processBlock(const void* data); 65 | /// process everything left in the internal buffer 66 | void processBuffer(); 67 | 68 | /// size of processed data in bytes 69 | uint64_t m_numBytes; 70 | /// valid bytes in m_buffer 71 | size_t m_bufferSize; 72 | /// bytes not processed yet 73 | uint8_t m_buffer[BlockSize]; 74 | 75 | enum { HashValues = HashBytes / 4 }; 76 | /// hash, stored as integers 77 | uint32_t m_hash[HashValues]; 78 | }; 79 | -------------------------------------------------------------------------------- /third_party/hash/include/sha3.h: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // sha3.h 3 | // Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | #pragma once 8 | 9 | //#include "hash.h" 10 | #include 11 | 12 | // define fixed size integer types 13 | #ifdef _MSC_VER 14 | // Windows 15 | typedef unsigned __int8 uint8_t; 16 | typedef unsigned __int64 uint64_t; 17 | #else 18 | // GCC 19 | #include 20 | #endif 21 | 22 | 23 | /// compute SHA3 hash 24 | /** Usage: 25 | SHA3 sha3; 26 | std::string myHash = sha3("Hello World"); // std::string 27 | std::string myHash2 = sha3("How are you", 11); // arbitrary data, 11 bytes 28 | 29 | // or in a streaming fashion: 30 | 31 | SHA3 sha3; 32 | while (more data available) 33 | sha3.add(pointer to fresh data, number of new bytes); 34 | std::string myHash3 = sha3.getHash(); 35 | */ 36 | class SHA3 //: public Hash 37 | { 38 | public: 39 | /// algorithm variants 40 | enum Bits { Bits224 = 224, Bits256 = 256, Bits384 = 384, Bits512 = 512 }; 41 | 42 | /// same as reset() 43 | explicit SHA3(Bits bits = Bits256); 44 | 45 | /// compute hash of a memory block 46 | std::string operator()(const void* data, size_t numBytes); 47 | /// compute hash of a string, excluding final zero 48 | std::string operator()(const std::string& text); 49 | 50 | /// add arbitrary number of bytes 51 | void add(const void* data, size_t numBytes); 52 | 53 | /// return latest hash as hex characters 54 | std::string getHash(); 55 | 56 | /// restart 57 | void reset(); 58 | 59 | private: 60 | /// process a full block 61 | void processBlock(const void* data); 62 | /// process everything left in the internal buffer 63 | void processBuffer(); 64 | 65 | /// 1600 bits, stored as 25x64 bit, BlockSize is no more than 1152 bits (Keccak224) 66 | enum { StateSize = 1600 / (8 * 8), 67 | MaxBlockSize = 200 - 2 * (224 / 8) }; 68 | 69 | /// hash 70 | uint64_t m_hash[StateSize]; 71 | /// size of processed data in bytes 72 | uint64_t m_numBytes; 73 | /// block size (less or equal to MaxBlockSize) 74 | size_t m_blockSize; 75 | /// valid bytes in m_buffer 76 | size_t m_bufferSize; 77 | /// bytes not processed yet 78 | uint8_t m_buffer[MaxBlockSize]; 79 | /// variant 80 | Bits m_bits; 81 | }; 82 | -------------------------------------------------------------------------------- /third_party/hash/src/digest.cpp: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // digest.cpp 3 | // Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | // g++ -O3 digest.cpp crc32.cpp md5.cpp sha1.cpp sha256.cpp keccak.cpp sha3.cpp -o digest 8 | 9 | #include "crc32.h" 10 | #include "md5.h" 11 | #include "sha1.h" 12 | #include "sha256.h" 13 | #include "keccak.h" 14 | #include "sha3.h" 15 | 16 | #include 17 | #include 18 | 19 | int main(int argc, char** argv) 20 | { 21 | // syntax check 22 | if (argc < 2 || argc > 3) 23 | { 24 | std::cout << "./digest filename [--crc|--md5|--sha1|--sha256|--keccak|--sha3]" << std::endl; 25 | return 1; 26 | } 27 | 28 | // parameters 29 | std::string filename = argv[1]; 30 | std::string algorithm = argc == 3 ? argv[2] : ""; 31 | bool computeCrc32 = algorithm.empty() || algorithm == "--crc"; 32 | bool computeMd5 = algorithm.empty() || algorithm == "--md5"; 33 | bool computeSha1 = algorithm.empty() || algorithm == "--sha1"; 34 | bool computeSha2 = algorithm.empty() || algorithm == "--sha2" || algorithm == "--sha256"; 35 | bool computeKeccak = algorithm.empty() || algorithm == "--keccak"; 36 | bool computeSha3 = algorithm.empty() || algorithm == "--sha3"; 37 | 38 | CRC32 digestCrc32; 39 | MD5 digestMd5; 40 | SHA1 digestSha1; 41 | SHA256 digestSha2; 42 | Keccak digestKeccak(Keccak::Keccak256); 43 | SHA3 digestSha3 (SHA3 ::Bits256); 44 | 45 | // each cycle processes about 1 MByte (divisible by 144 => improves Keccak/SHA3 performance) 46 | const size_t BufferSize = 144*7*1024; 47 | char* buffer = new char[BufferSize]; 48 | 49 | // select input source: either file or standard-in 50 | std::ifstream file; 51 | std::istream* input = NULL; 52 | // accept std::cin, syntax will be: "./digest - --sha3 < data" 53 | if (filename == "-") 54 | { 55 | input = &std::cin; 56 | } 57 | else 58 | { 59 | // open file 60 | file.open(filename.c_str(), std::ios::in | std::ios::binary); 61 | if (!file) 62 | { 63 | std::cerr << "Can't open '" << filename << "'" << std::endl; 64 | return 2; 65 | } 66 | 67 | input = &file; 68 | } 69 | 70 | // process file 71 | while (*input) 72 | { 73 | input->read(buffer, BufferSize); 74 | std::size_t numBytesRead = size_t(input->gcount()); 75 | 76 | if (computeCrc32) 77 | digestCrc32 .add(buffer, numBytesRead); 78 | if (computeMd5) 79 | digestMd5 .add(buffer, numBytesRead); 80 | if (computeSha1) 81 | digestSha1 .add(buffer, numBytesRead); 82 | if (computeSha2) 83 | digestSha2 .add(buffer, numBytesRead); 84 | if (computeKeccak) 85 | digestKeccak.add(buffer, numBytesRead); 86 | if (computeSha3) 87 | digestSha3 .add(buffer, numBytesRead); 88 | } 89 | 90 | // clean up 91 | file.close(); 92 | delete[] buffer; 93 | 94 | // show results 95 | if (computeCrc32) 96 | std::cout << "CRC32: " << digestCrc32 .getHash() << std::endl; 97 | if (computeMd5) 98 | std::cout << "MD5: " << digestMd5 .getHash() << std::endl; 99 | if (computeSha1) 100 | std::cout << "SHA1: " << digestSha1 .getHash() << std::endl; 101 | if (computeSha2) 102 | std::cout << "SHA2/256: " << digestSha2 .getHash() << std::endl; 103 | if (computeKeccak) 104 | std::cout << "Keccak/256: " << digestKeccak.getHash() << std::endl; 105 | if (computeSha3) 106 | std::cout << "SHA3/256: " << digestSha3 .getHash() << std::endl; 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /third_party/hash/src/keccak.cpp: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // keccak.cpp 3 | // Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | #include "keccak.h" 8 | 9 | // big endian architectures need #define __BYTE_ORDER __BIG_ENDIAN 10 | #ifndef _MSC_VER 11 | #endif 12 | 13 | 14 | /// same as reset() 15 | Keccak::Keccak(Bits bits) 16 | : m_blockSize(200 - 2 * (bits / 8)), 17 | m_bits(bits) 18 | { 19 | reset(); 20 | } 21 | 22 | 23 | /// restart 24 | void Keccak::reset() 25 | { 26 | for (size_t i = 0; i < StateSize; i++) 27 | m_hash[i] = 0; 28 | 29 | m_numBytes = 0; 30 | m_bufferSize = 0; 31 | } 32 | 33 | 34 | /// constants and local helper functions 35 | namespace 36 | { 37 | const unsigned int KeccakRounds = 24; 38 | const uint64_t XorMasks[KeccakRounds] = 39 | { 40 | 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 41 | 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL, 42 | 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, 43 | 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL, 44 | 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 45 | 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, 46 | 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL, 47 | 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL 48 | }; 49 | 50 | /// rotate left and wrap around to the right 51 | inline uint64_t rotateLeft(uint64_t x, uint8_t numBits) 52 | { 53 | return (x << numBits) | (x >> (64 - numBits)); 54 | } 55 | 56 | /// convert litte vs big endian 57 | inline uint64_t swap(uint64_t x) 58 | { 59 | #if defined(__GNUC__) || defined(__clang__) 60 | return __builtin_bswap64(x); 61 | #endif 62 | #ifdef _MSC_VER 63 | return _byteswap_uint64(x); 64 | #endif 65 | 66 | return (x >> 56) | 67 | ((x >> 40) & 0x000000000000FF00ULL) | 68 | ((x >> 24) & 0x0000000000FF0000ULL) | 69 | ((x >> 8) & 0x00000000FF000000ULL) | 70 | ((x << 8) & 0x000000FF00000000ULL) | 71 | ((x << 24) & 0x0000FF0000000000ULL) | 72 | ((x << 40) & 0x00FF000000000000ULL) | 73 | (x << 56); 74 | } 75 | 76 | 77 | /// return x % 5 for 0 <= x <= 9 78 | unsigned int mod5(unsigned int x) 79 | { 80 | if (x < 5) 81 | return x; 82 | 83 | return x - 5; 84 | } 85 | } 86 | 87 | 88 | /// process a full block 89 | void Keccak::processBlock(const void* data) 90 | { 91 | #if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN) 92 | #define LITTLEENDIAN(x) swap(x) 93 | #else 94 | #define LITTLEENDIAN(x) (x) 95 | #endif 96 | 97 | const uint64_t* data64 = (const uint64_t*) data; 98 | // mix data into state 99 | for (unsigned int i = 0; i < m_blockSize / 8; i++) 100 | m_hash[i] ^= LITTLEENDIAN(data64[i]); 101 | 102 | // re-compute state 103 | for (unsigned int round = 0; round < KeccakRounds; round++) 104 | { 105 | // Theta 106 | uint64_t coefficients[5]; 107 | for (unsigned int i = 0; i < 5; i++) 108 | coefficients[i] = m_hash[i] ^ m_hash[i + 5] ^ m_hash[i + 10] ^ m_hash[i + 15] ^ m_hash[i + 20]; 109 | 110 | for (unsigned int i = 0; i < 5; i++) 111 | { 112 | uint64_t one = coefficients[mod5(i + 4)] ^ rotateLeft(coefficients[mod5(i + 1)], 1); 113 | m_hash[i ] ^= one; 114 | m_hash[i + 5] ^= one; 115 | m_hash[i + 10] ^= one; 116 | m_hash[i + 15] ^= one; 117 | m_hash[i + 20] ^= one; 118 | } 119 | 120 | // temporary 121 | uint64_t one; 122 | 123 | // Rho Pi 124 | uint64_t last = m_hash[1]; 125 | one = m_hash[10]; m_hash[10] = rotateLeft(last, 1); last = one; 126 | one = m_hash[ 7]; m_hash[ 7] = rotateLeft(last, 3); last = one; 127 | one = m_hash[11]; m_hash[11] = rotateLeft(last, 6); last = one; 128 | one = m_hash[17]; m_hash[17] = rotateLeft(last, 10); last = one; 129 | one = m_hash[18]; m_hash[18] = rotateLeft(last, 15); last = one; 130 | one = m_hash[ 3]; m_hash[ 3] = rotateLeft(last, 21); last = one; 131 | one = m_hash[ 5]; m_hash[ 5] = rotateLeft(last, 28); last = one; 132 | one = m_hash[16]; m_hash[16] = rotateLeft(last, 36); last = one; 133 | one = m_hash[ 8]; m_hash[ 8] = rotateLeft(last, 45); last = one; 134 | one = m_hash[21]; m_hash[21] = rotateLeft(last, 55); last = one; 135 | one = m_hash[24]; m_hash[24] = rotateLeft(last, 2); last = one; 136 | one = m_hash[ 4]; m_hash[ 4] = rotateLeft(last, 14); last = one; 137 | one = m_hash[15]; m_hash[15] = rotateLeft(last, 27); last = one; 138 | one = m_hash[23]; m_hash[23] = rotateLeft(last, 41); last = one; 139 | one = m_hash[19]; m_hash[19] = rotateLeft(last, 56); last = one; 140 | one = m_hash[13]; m_hash[13] = rotateLeft(last, 8); last = one; 141 | one = m_hash[12]; m_hash[12] = rotateLeft(last, 25); last = one; 142 | one = m_hash[ 2]; m_hash[ 2] = rotateLeft(last, 43); last = one; 143 | one = m_hash[20]; m_hash[20] = rotateLeft(last, 62); last = one; 144 | one = m_hash[14]; m_hash[14] = rotateLeft(last, 18); last = one; 145 | one = m_hash[22]; m_hash[22] = rotateLeft(last, 39); last = one; 146 | one = m_hash[ 9]; m_hash[ 9] = rotateLeft(last, 61); last = one; 147 | one = m_hash[ 6]; m_hash[ 6] = rotateLeft(last, 20); last = one; 148 | m_hash[ 1] = rotateLeft(last, 44); 149 | 150 | // Chi 151 | for (unsigned int j = 0; j < StateSize; j += 5) 152 | { 153 | // temporaries 154 | uint64_t one = m_hash[j]; 155 | uint64_t two = m_hash[j + 1]; 156 | 157 | m_hash[j] ^= m_hash[j + 2] & ~two; 158 | m_hash[j + 1] ^= m_hash[j + 3] & ~m_hash[j + 2]; 159 | m_hash[j + 2] ^= m_hash[j + 4] & ~m_hash[j + 3]; 160 | m_hash[j + 3] ^= one & ~m_hash[j + 4]; 161 | m_hash[j + 4] ^= two & ~one; 162 | } 163 | 164 | // Iota 165 | m_hash[0] ^= XorMasks[round]; 166 | } 167 | } 168 | 169 | 170 | /// add arbitrary number of bytes 171 | void Keccak::add(const void* data, size_t numBytes) 172 | { 173 | const uint8_t* current = (const uint8_t*) data; 174 | 175 | if (m_bufferSize > 0) 176 | { 177 | while (numBytes > 0 && m_bufferSize < m_blockSize) 178 | { 179 | m_buffer[m_bufferSize++] = *current++; 180 | numBytes--; 181 | } 182 | } 183 | 184 | // full buffer 185 | if (m_bufferSize == m_blockSize) 186 | { 187 | processBlock((void*)m_buffer); 188 | m_numBytes += m_blockSize; 189 | m_bufferSize = 0; 190 | } 191 | 192 | // no more data ? 193 | if (numBytes == 0) 194 | return; 195 | 196 | // process full blocks 197 | while (numBytes >= m_blockSize) 198 | { 199 | processBlock(current); 200 | current += m_blockSize; 201 | m_numBytes += m_blockSize; 202 | numBytes -= m_blockSize; 203 | } 204 | 205 | // keep remaining bytes in buffer 206 | while (numBytes > 0) 207 | { 208 | m_buffer[m_bufferSize++] = *current++; 209 | numBytes--; 210 | } 211 | } 212 | 213 | 214 | /// process everything left in the internal buffer 215 | void Keccak::processBuffer() 216 | { 217 | unsigned int blockSize = 200 - 2 * (m_bits / 8); 218 | 219 | // add padding 220 | size_t offset = m_bufferSize; 221 | // add a "1" byte 222 | m_buffer[offset++] = 1; 223 | // fill with zeros 224 | while (offset < blockSize) 225 | m_buffer[offset++] = 0; 226 | 227 | // and add a single set bit 228 | m_buffer[blockSize - 1] |= 0x80; 229 | 230 | processBlock(m_buffer); 231 | } 232 | 233 | 234 | /// return latest hash as 16 hex characters 235 | std::string Keccak::getHash() 236 | { 237 | // save hash state 238 | uint64_t oldHash[StateSize]; 239 | for (unsigned int i = 0; i < StateSize; i++) 240 | oldHash[i] = m_hash[i]; 241 | 242 | // process remaining bytes 243 | processBuffer(); 244 | 245 | // convert hash to string 246 | static const char dec2hex[16 + 1] = "0123456789abcdef"; 247 | 248 | // number of significant elements in hash (uint64_t) 249 | unsigned int hashLength = m_bits / 64; 250 | 251 | std::string result; 252 | for (unsigned int i = 0; i < hashLength; i++) 253 | for (unsigned int j = 0; j < 8; j++) // 64 bits => 8 bytes 254 | { 255 | // convert a byte to hex 256 | unsigned char oneByte = (unsigned char) (m_hash[i] >> (8 * j)); 257 | result += dec2hex[oneByte >> 4]; 258 | result += dec2hex[oneByte & 15]; 259 | } 260 | 261 | // Keccak224's last entry in m_hash provides only 32 bits instead of 64 bits 262 | unsigned int remainder = m_bits - hashLength * 64; 263 | unsigned int processed = 0; 264 | while (processed < remainder) 265 | { 266 | // convert a byte to hex 267 | unsigned char oneByte = (unsigned char) (m_hash[hashLength] >> processed); 268 | result += dec2hex[oneByte >> 4]; 269 | result += dec2hex[oneByte & 15]; 270 | 271 | processed += 8; 272 | } 273 | 274 | // restore state 275 | for (unsigned int i = 0; i < StateSize; i++) 276 | m_hash[i] = oldHash[i]; 277 | 278 | return result; 279 | } 280 | 281 | 282 | /// compute Keccak hash of a memory block 283 | std::string Keccak::operator()(const void* data, size_t numBytes) 284 | { 285 | reset(); 286 | add(data, numBytes); 287 | return getHash(); 288 | } 289 | 290 | 291 | /// compute Keccak hash of a string, excluding final zero 292 | std::string Keccak::operator()(const std::string& text) 293 | { 294 | reset(); 295 | add(text.c_str(), text.size()); 296 | return getHash(); 297 | } 298 | -------------------------------------------------------------------------------- /third_party/hash/src/sha1.cpp: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // sha1.cpp 3 | // Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | #include "sha1.h" 8 | 9 | // big endian architectures need #define __BYTE_ORDER __BIG_ENDIAN 10 | #ifndef _MSC_VER 11 | #endif 12 | 13 | 14 | /// same as reset() 15 | SHA1::SHA1() 16 | { 17 | reset(); 18 | } 19 | 20 | 21 | /// restart 22 | void SHA1::reset() 23 | { 24 | m_numBytes = 0; 25 | m_bufferSize = 0; 26 | 27 | // according to RFC 1321 28 | m_hash[0] = 0x67452301; 29 | m_hash[1] = 0xefcdab89; 30 | m_hash[2] = 0x98badcfe; 31 | m_hash[3] = 0x10325476; 32 | m_hash[4] = 0xc3d2e1f0; 33 | } 34 | 35 | 36 | namespace 37 | { 38 | // mix functions for processBlock() 39 | inline uint32_t f1(uint32_t b, uint32_t c, uint32_t d) 40 | { 41 | return d ^ (b & (c ^ d)); // original: f = (b & c) | ((~b) & d); 42 | } 43 | 44 | inline uint32_t f2(uint32_t b, uint32_t c, uint32_t d) 45 | { 46 | return b ^ c ^ d; 47 | } 48 | 49 | inline uint32_t f3(uint32_t b, uint32_t c, uint32_t d) 50 | { 51 | return (b & c) | (b & d) | (c & d); 52 | } 53 | 54 | inline uint32_t rotate(uint32_t a, uint32_t c) 55 | { 56 | return (a << c) | (a >> (32 - c)); 57 | } 58 | 59 | inline uint32_t swap(uint32_t x) 60 | { 61 | #if defined(__GNUC__) || defined(__clang__) 62 | return __builtin_bswap32(x); 63 | #endif 64 | #ifdef MSC_VER 65 | return _byteswap_ulong(x); 66 | #endif 67 | 68 | return (x >> 24) | 69 | ((x >> 8) & 0x0000FF00) | 70 | ((x << 8) & 0x00FF0000) | 71 | (x << 24); 72 | } 73 | } 74 | 75 | 76 | /// process 64 bytes 77 | void SHA1::processBlock(const void* data) 78 | { 79 | // get last hash 80 | uint32_t a = m_hash[0]; 81 | uint32_t b = m_hash[1]; 82 | uint32_t c = m_hash[2]; 83 | uint32_t d = m_hash[3]; 84 | uint32_t e = m_hash[4]; 85 | 86 | // data represented as 16x 32-bit words 87 | const uint32_t* input = (uint32_t*) data; 88 | // convert to big endian 89 | uint32_t words[80]; 90 | for (int i = 0; i < 16; i++) 91 | #if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN) 92 | words[i] = input[i]; 93 | #else 94 | words[i] = swap(input[i]); 95 | #endif 96 | 97 | // extend to 80 words 98 | for (int i = 16; i < 80; i++) 99 | words[i] = rotate(words[i-3] ^ words[i-8] ^ words[i-14] ^ words[i-16], 1); 100 | 101 | // first round 102 | for (int i = 0; i < 4; i++) 103 | { 104 | int offset = 5*i; 105 | e += rotate(a,5) + f1(b,c,d) + words[offset ] + 0x5a827999; b = rotate(b,30); 106 | d += rotate(e,5) + f1(a,b,c) + words[offset+1] + 0x5a827999; a = rotate(a,30); 107 | c += rotate(d,5) + f1(e,a,b) + words[offset+2] + 0x5a827999; e = rotate(e,30); 108 | b += rotate(c,5) + f1(d,e,a) + words[offset+3] + 0x5a827999; d = rotate(d,30); 109 | a += rotate(b,5) + f1(c,d,e) + words[offset+4] + 0x5a827999; c = rotate(c,30); 110 | } 111 | 112 | // second round 113 | for (int i = 4; i < 8; i++) 114 | { 115 | int offset = 5*i; 116 | e += rotate(a,5) + f2(b,c,d) + words[offset ] + 0x6ed9eba1; b = rotate(b,30); 117 | d += rotate(e,5) + f2(a,b,c) + words[offset+1] + 0x6ed9eba1; a = rotate(a,30); 118 | c += rotate(d,5) + f2(e,a,b) + words[offset+2] + 0x6ed9eba1; e = rotate(e,30); 119 | b += rotate(c,5) + f2(d,e,a) + words[offset+3] + 0x6ed9eba1; d = rotate(d,30); 120 | a += rotate(b,5) + f2(c,d,e) + words[offset+4] + 0x6ed9eba1; c = rotate(c,30); 121 | } 122 | 123 | // third round 124 | for (int i = 8; i < 12; i++) 125 | { 126 | int offset = 5*i; 127 | e += rotate(a,5) + f3(b,c,d) + words[offset ] + 0x8f1bbcdc; b = rotate(b,30); 128 | d += rotate(e,5) + f3(a,b,c) + words[offset+1] + 0x8f1bbcdc; a = rotate(a,30); 129 | c += rotate(d,5) + f3(e,a,b) + words[offset+2] + 0x8f1bbcdc; e = rotate(e,30); 130 | b += rotate(c,5) + f3(d,e,a) + words[offset+3] + 0x8f1bbcdc; d = rotate(d,30); 131 | a += rotate(b,5) + f3(c,d,e) + words[offset+4] + 0x8f1bbcdc; c = rotate(c,30); 132 | } 133 | 134 | // fourth round 135 | for (int i = 12; i < 16; i++) 136 | { 137 | int offset = 5*i; 138 | e += rotate(a,5) + f2(b,c,d) + words[offset ] + 0xca62c1d6; b = rotate(b,30); 139 | d += rotate(e,5) + f2(a,b,c) + words[offset+1] + 0xca62c1d6; a = rotate(a,30); 140 | c += rotate(d,5) + f2(e,a,b) + words[offset+2] + 0xca62c1d6; e = rotate(e,30); 141 | b += rotate(c,5) + f2(d,e,a) + words[offset+3] + 0xca62c1d6; d = rotate(d,30); 142 | a += rotate(b,5) + f2(c,d,e) + words[offset+4] + 0xca62c1d6; c = rotate(c,30); 143 | } 144 | 145 | // update hash 146 | m_hash[0] += a; 147 | m_hash[1] += b; 148 | m_hash[2] += c; 149 | m_hash[3] += d; 150 | m_hash[4] += e; 151 | } 152 | 153 | 154 | /// add arbitrary number of bytes 155 | void SHA1::add(const void* data, size_t numBytes) 156 | { 157 | const uint8_t* current = (const uint8_t*) data; 158 | 159 | if (m_bufferSize > 0) 160 | { 161 | while (numBytes > 0 && m_bufferSize < BlockSize) 162 | { 163 | m_buffer[m_bufferSize++] = *current++; 164 | numBytes--; 165 | } 166 | } 167 | 168 | // full buffer 169 | if (m_bufferSize == BlockSize) 170 | { 171 | processBlock((void*)m_buffer); 172 | m_numBytes += BlockSize; 173 | m_bufferSize = 0; 174 | } 175 | 176 | // no more data ? 177 | if (numBytes == 0) 178 | return; 179 | 180 | // process full blocks 181 | while (numBytes >= BlockSize) 182 | { 183 | processBlock(current); 184 | current += BlockSize; 185 | m_numBytes += BlockSize; 186 | numBytes -= BlockSize; 187 | } 188 | 189 | // keep remaining bytes in buffer 190 | while (numBytes > 0) 191 | { 192 | m_buffer[m_bufferSize++] = *current++; 193 | numBytes--; 194 | } 195 | } 196 | 197 | 198 | /// process final block, less than 64 bytes 199 | void SHA1::processBuffer() 200 | { 201 | // the input bytes are considered as bits strings, where the first bit is the most significant bit of the byte 202 | 203 | // - append "1" bit to message 204 | // - append "0" bits until message length in bit mod 512 is 448 205 | // - append length as 64 bit integer 206 | 207 | // number of bits 208 | size_t paddedLength = m_bufferSize * 8; 209 | 210 | // plus one bit set to 1 (always appended) 211 | paddedLength++; 212 | 213 | // number of bits must be (numBits % 512) = 448 214 | size_t lower11Bits = paddedLength & 511; 215 | if (lower11Bits <= 448) 216 | paddedLength += 448 - lower11Bits; 217 | else 218 | paddedLength += 512 + 448 - lower11Bits; 219 | // convert from bits to bytes 220 | paddedLength /= 8; 221 | 222 | // only needed if additional data flows over into a second block 223 | unsigned char extra[BlockSize]; 224 | 225 | // append a "1" bit, 128 => binary 10000000 226 | if (m_bufferSize < BlockSize) 227 | m_buffer[m_bufferSize] = 128; 228 | else 229 | extra[0] = 128; 230 | 231 | size_t i; 232 | for (i = m_bufferSize + 1; i < BlockSize; i++) 233 | m_buffer[i] = 0; 234 | for (; i < paddedLength; i++) 235 | extra[i - BlockSize] = 0; 236 | 237 | // add message length in bits as 64 bit number 238 | uint64_t msgBits = 8 * (m_numBytes + m_bufferSize); 239 | // find right position 240 | unsigned char* addLength; 241 | if (paddedLength < BlockSize) 242 | addLength = m_buffer + paddedLength; 243 | else 244 | addLength = extra + paddedLength - BlockSize; 245 | 246 | // must be big endian 247 | *addLength++ = (unsigned char)((msgBits >> 56) & 0xFF); 248 | *addLength++ = (unsigned char)((msgBits >> 48) & 0xFF); 249 | *addLength++ = (unsigned char)((msgBits >> 40) & 0xFF); 250 | *addLength++ = (unsigned char)((msgBits >> 32) & 0xFF); 251 | *addLength++ = (unsigned char)((msgBits >> 24) & 0xFF); 252 | *addLength++ = (unsigned char)((msgBits >> 16) & 0xFF); 253 | *addLength++ = (unsigned char)((msgBits >> 8) & 0xFF); 254 | *addLength = (unsigned char)( msgBits & 0xFF); 255 | 256 | // process blocks 257 | processBlock(m_buffer); 258 | // flowed over into a second block ? 259 | if (paddedLength > BlockSize) 260 | processBlock(extra); 261 | } 262 | 263 | 264 | /// return latest hash as 40 hex characters 265 | std::string SHA1::getHash() 266 | { 267 | // compute hash (as raw bytes) 268 | unsigned char rawHash[HashBytes]; 269 | getHash(rawHash); 270 | 271 | // convert to hex string 272 | std::string result; 273 | result.reserve(2 * HashBytes); 274 | for (int i = 0; i < HashBytes; i++) 275 | { 276 | static const char dec2hex[16+1] = "0123456789abcdef"; 277 | result += dec2hex[(rawHash[i] >> 4) & 15]; 278 | result += dec2hex[ rawHash[i] & 15]; 279 | } 280 | 281 | return result; 282 | } 283 | 284 | 285 | /// return latest hash as bytes 286 | void SHA1::getHash(unsigned char buffer[SHA1::HashBytes]) 287 | { 288 | // save old hash if buffer is partially filled 289 | uint32_t oldHash[HashValues]; 290 | for (int i = 0; i < HashValues; i++) 291 | oldHash[i] = m_hash[i]; 292 | 293 | // process remaining bytes 294 | processBuffer(); 295 | 296 | unsigned char* current = buffer; 297 | for (int i = 0; i < HashValues; i++) 298 | { 299 | *current++ = (m_hash[i] >> 24) & 0xFF; 300 | *current++ = (m_hash[i] >> 16) & 0xFF; 301 | *current++ = (m_hash[i] >> 8) & 0xFF; 302 | *current++ = m_hash[i] & 0xFF; 303 | 304 | // restore old hash 305 | m_hash[i] = oldHash[i]; 306 | } 307 | } 308 | 309 | 310 | /// compute SHA1 of a memory block 311 | std::string SHA1::operator()(const void* data, size_t numBytes) 312 | { 313 | reset(); 314 | add(data, numBytes); 315 | return getHash(); 316 | } 317 | 318 | 319 | /// compute SHA1 of a string, excluding final zero 320 | std::string SHA1::operator()(const std::string& text) 321 | { 322 | reset(); 323 | add(text.c_str(), text.size()); 324 | return getHash(); 325 | } 326 | -------------------------------------------------------------------------------- /third_party/hash/src/sha3.cpp: -------------------------------------------------------------------------------- 1 | // ////////////////////////////////////////////////////////// 2 | // sha3.cpp 3 | // Copyright (c) 2014,2015 Stephan Brumme. All rights reserved. 4 | // see http://create.stephan-brumme.com/disclaimer.html 5 | // 6 | 7 | #include "sha3.h" 8 | 9 | // big endian architectures need #define __BYTE_ORDER __BIG_ENDIAN 10 | #ifndef _MSC_VER 11 | #endif 12 | 13 | #include 14 | 15 | 16 | /// same as reset() 17 | SHA3::SHA3(Bits bits) 18 | : m_blockSize(200 - 2 * (bits / 8)), 19 | m_bits(bits) 20 | { 21 | reset(); 22 | } 23 | 24 | 25 | /// restart 26 | void SHA3::reset() 27 | { 28 | for (size_t i = 0; i < StateSize; i++) 29 | m_hash[i] = 0; 30 | 31 | m_numBytes = 0; 32 | m_bufferSize = 0; 33 | } 34 | 35 | 36 | /// constants and local helper functions 37 | namespace 38 | { 39 | const unsigned int Rounds = 24; 40 | const uint64_t XorMasks[Rounds] = 41 | { 42 | 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 43 | 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL, 44 | 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, 45 | 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL, 46 | 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 47 | 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, 48 | 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL, 49 | 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL 50 | }; 51 | 52 | /// rotate left and wrap around to the right 53 | inline uint64_t rotateLeft(uint64_t x, uint8_t numBits) 54 | { 55 | return (x << numBits) | (x >> (64 - numBits)); 56 | } 57 | 58 | /// convert litte vs big endian 59 | inline uint64_t swap(uint64_t x) 60 | { 61 | #if defined(__GNUC__) || defined(__clang__) 62 | return __builtin_bswap64(x); 63 | #endif 64 | #ifdef _MSC_VER 65 | return _byteswap_uint64(x); 66 | #endif 67 | 68 | return (x >> 56) | 69 | ((x >> 40) & 0x000000000000FF00ULL) | 70 | ((x >> 24) & 0x0000000000FF0000ULL) | 71 | ((x >> 8) & 0x00000000FF000000ULL) | 72 | ((x << 8) & 0x000000FF00000000ULL) | 73 | ((x << 24) & 0x0000FF0000000000ULL) | 74 | ((x << 40) & 0x00FF000000000000ULL) | 75 | (x << 56); 76 | } 77 | 78 | 79 | /// return x % 5 for 0 <= x <= 9 80 | unsigned int mod5(unsigned int x) 81 | { 82 | if (x < 5) 83 | return x; 84 | 85 | return x - 5; 86 | } 87 | } 88 | 89 | 90 | /// process a full block 91 | void SHA3::processBlock(const void* data) 92 | { 93 | #if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN) 94 | #define LITTLEENDIAN(x) swap(x) 95 | #else 96 | #define LITTLEENDIAN(x) (x) 97 | #endif 98 | 99 | const uint64_t* data64 = (const uint64_t*) data; 100 | // mix data into state 101 | for (unsigned int i = 0; i < m_blockSize / 8; i++) 102 | m_hash[i] ^= LITTLEENDIAN(data64[i]); 103 | 104 | // re-compute state 105 | for (unsigned int round = 0; round < Rounds; round++) 106 | { 107 | // Theta 108 | uint64_t coefficients[5]; 109 | for (unsigned int i = 0; i < 5; i++) 110 | coefficients[i] = m_hash[i] ^ m_hash[i + 5] ^ m_hash[i + 10] ^ m_hash[i + 15] ^ m_hash[i + 20]; 111 | 112 | for (unsigned int i = 0; i < 5; i++) 113 | { 114 | uint64_t one = coefficients[mod5(i + 4)] ^ rotateLeft(coefficients[mod5(i + 1)], 1); 115 | m_hash[i ] ^= one; 116 | m_hash[i + 5] ^= one; 117 | m_hash[i + 10] ^= one; 118 | m_hash[i + 15] ^= one; 119 | m_hash[i + 20] ^= one; 120 | } 121 | 122 | // temporary 123 | uint64_t one; 124 | 125 | // Rho Pi 126 | uint64_t last = m_hash[1]; 127 | one = m_hash[10]; m_hash[10] = rotateLeft(last, 1); last = one; 128 | one = m_hash[ 7]; m_hash[ 7] = rotateLeft(last, 3); last = one; 129 | one = m_hash[11]; m_hash[11] = rotateLeft(last, 6); last = one; 130 | one = m_hash[17]; m_hash[17] = rotateLeft(last, 10); last = one; 131 | one = m_hash[18]; m_hash[18] = rotateLeft(last, 15); last = one; 132 | one = m_hash[ 3]; m_hash[ 3] = rotateLeft(last, 21); last = one; 133 | one = m_hash[ 5]; m_hash[ 5] = rotateLeft(last, 28); last = one; 134 | one = m_hash[16]; m_hash[16] = rotateLeft(last, 36); last = one; 135 | one = m_hash[ 8]; m_hash[ 8] = rotateLeft(last, 45); last = one; 136 | one = m_hash[21]; m_hash[21] = rotateLeft(last, 55); last = one; 137 | one = m_hash[24]; m_hash[24] = rotateLeft(last, 2); last = one; 138 | one = m_hash[ 4]; m_hash[ 4] = rotateLeft(last, 14); last = one; 139 | one = m_hash[15]; m_hash[15] = rotateLeft(last, 27); last = one; 140 | one = m_hash[23]; m_hash[23] = rotateLeft(last, 41); last = one; 141 | one = m_hash[19]; m_hash[19] = rotateLeft(last, 56); last = one; 142 | one = m_hash[13]; m_hash[13] = rotateLeft(last, 8); last = one; 143 | one = m_hash[12]; m_hash[12] = rotateLeft(last, 25); last = one; 144 | one = m_hash[ 2]; m_hash[ 2] = rotateLeft(last, 43); last = one; 145 | one = m_hash[20]; m_hash[20] = rotateLeft(last, 62); last = one; 146 | one = m_hash[14]; m_hash[14] = rotateLeft(last, 18); last = one; 147 | one = m_hash[22]; m_hash[22] = rotateLeft(last, 39); last = one; 148 | one = m_hash[ 9]; m_hash[ 9] = rotateLeft(last, 61); last = one; 149 | one = m_hash[ 6]; m_hash[ 6] = rotateLeft(last, 20); last = one; 150 | m_hash[ 1] = rotateLeft(last, 44); 151 | 152 | // Chi 153 | for (unsigned int j = 0; j < StateSize; j += 5) 154 | { 155 | // temporaries 156 | uint64_t one = m_hash[j]; 157 | uint64_t two = m_hash[j + 1]; 158 | 159 | m_hash[j] ^= m_hash[j + 2] & ~two; 160 | m_hash[j + 1] ^= m_hash[j + 3] & ~m_hash[j + 2]; 161 | m_hash[j + 2] ^= m_hash[j + 4] & ~m_hash[j + 3]; 162 | m_hash[j + 3] ^= one & ~m_hash[j + 4]; 163 | m_hash[j + 4] ^= two & ~one; 164 | } 165 | 166 | // Iota 167 | m_hash[0] ^= XorMasks[round]; 168 | } 169 | } 170 | 171 | 172 | /// add arbitrary number of bytes 173 | void SHA3::add(const void* data, size_t numBytes) 174 | { 175 | const uint8_t* current = (const uint8_t*) data; 176 | 177 | // copy data to buffer 178 | if (m_bufferSize > 0) 179 | { 180 | while (numBytes > 0 && m_bufferSize < m_blockSize) 181 | { 182 | m_buffer[m_bufferSize++] = *current++; 183 | numBytes--; 184 | } 185 | } 186 | 187 | // full buffer 188 | if (m_bufferSize == m_blockSize) 189 | { 190 | processBlock((void*)m_buffer); 191 | m_numBytes += m_blockSize; 192 | m_bufferSize = 0; 193 | } 194 | 195 | // no more data ? 196 | if (numBytes == 0) 197 | return; 198 | 199 | // process full blocks 200 | while (numBytes >= m_blockSize) 201 | { 202 | processBlock(current); 203 | current += m_blockSize; 204 | m_numBytes += m_blockSize; 205 | numBytes -= m_blockSize; 206 | } 207 | 208 | // keep remaining bytes in buffer 209 | while (numBytes > 0) 210 | { 211 | m_buffer[m_bufferSize++] = *current++; 212 | numBytes--; 213 | } 214 | } 215 | 216 | 217 | /// process everything left in the internal buffer 218 | void SHA3::processBuffer() 219 | { 220 | // add padding 221 | size_t offset = m_bufferSize; 222 | // add a "1" byte 223 | m_buffer[offset++] = 0x06; 224 | // fill with zeros 225 | while (offset < m_blockSize) 226 | m_buffer[offset++] = 0; 227 | 228 | // and add a single set bit 229 | m_buffer[offset - 1] |= 0x80; 230 | 231 | processBlock(m_buffer); 232 | } 233 | 234 | 235 | /// return latest hash as 16 hex characters 236 | std::string SHA3::getHash() 237 | { 238 | // save hash state 239 | uint64_t oldHash[StateSize]; 240 | for (unsigned int i = 0; i < StateSize; i++) 241 | oldHash[i] = m_hash[i]; 242 | 243 | // process remaining bytes 244 | processBuffer(); 245 | 246 | // convert hash to string 247 | static const char dec2hex[16 + 1] = "0123456789abcdef"; 248 | 249 | // number of significant elements in hash (uint64_t) 250 | unsigned int hashLength = m_bits / 64; 251 | 252 | std::string result; 253 | result.reserve(m_bits / 4); 254 | for (unsigned int i = 0; i < hashLength; i++) 255 | for (unsigned int j = 0; j < 8; j++) // 64 bits => 8 bytes 256 | { 257 | // convert a byte to hex 258 | unsigned char oneByte = (unsigned char) (m_hash[i] >> (8 * j)); 259 | result += dec2hex[oneByte >> 4]; 260 | result += dec2hex[oneByte & 15]; 261 | } 262 | 263 | // SHA3-224's last entry in m_hash provides only 32 bits instead of 64 bits 264 | unsigned int remainder = m_bits - hashLength * 64; 265 | unsigned int processed = 0; 266 | while (processed < remainder) 267 | { 268 | // convert a byte to hex 269 | unsigned char oneByte = (unsigned char) (m_hash[hashLength] >> processed); 270 | result += dec2hex[oneByte >> 4]; 271 | result += dec2hex[oneByte & 15]; 272 | 273 | processed += 8; 274 | } 275 | 276 | // restore state 277 | for (unsigned int i = 0; i < StateSize; i++) 278 | m_hash[i] = oldHash[i]; 279 | 280 | return result; 281 | } 282 | 283 | 284 | /// compute SHA3 of a memory block 285 | std::string SHA3::operator()(const void* data, size_t numBytes) 286 | { 287 | reset(); 288 | add(data, numBytes); 289 | return getHash(); 290 | } 291 | 292 | 293 | /// compute SHA3 of a string, excluding final zero 294 | std::string SHA3::operator()(const std::string& text) 295 | { 296 | reset(); 297 | add(text.c_str(), text.size()); 298 | return getHash(); 299 | } 300 | --------------------------------------------------------------------------------