├── .gitignore ├── CHANGELOG.md ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake ├── FindCPP-NETLIB.cmake ├── FindGMock.cmake └── FindJsonCpp.cmake ├── doc ├── CMakeLists.txt ├── doxygen.extra.css ├── doxygen.h └── doxygen.in ├── include ├── CMakeLists.txt └── retdec │ ├── analysis.h │ ├── analysis_arguments.h │ ├── decompilation.h │ ├── decompilation_arguments.h │ ├── decompiler.h │ ├── exceptions.h │ ├── file.h │ ├── fileinfo.h │ ├── fwd_decls.h │ ├── internal │ ├── connection.h │ ├── connection_manager.h │ ├── connection_managers │ │ └── real_connection_manager.h │ ├── connections │ │ └── real_connection.h │ ├── files │ │ ├── filesystem_file.h │ │ └── string_file.h │ ├── resource_impl.h │ ├── service_impl.h │ ├── service_with_resources_impl.h │ └── utilities │ │ ├── connection.h │ │ ├── container.h │ │ ├── json.h │ │ ├── os.h │ │ ├── smart_ptr.h │ │ └── string.h │ ├── resource.h │ ├── resource_arguments.h │ ├── retdec.h │ ├── service.h │ ├── settings.h │ └── test.h ├── src ├── CMakeLists.txt ├── retdec │ ├── CMakeLists.txt │ ├── analysis.cpp │ ├── analysis_arguments.cpp │ ├── decompilation.cpp │ ├── decompilation_arguments.cpp │ ├── decompiler.cpp │ ├── exceptions.cpp │ ├── file.cpp │ ├── fileinfo.cpp │ ├── internal │ │ ├── connection.cpp │ │ ├── connection_manager.cpp │ │ ├── connection_managers │ │ │ └── real_connection_manager.cpp │ │ ├── connections │ │ │ └── real_connection.cpp │ │ ├── files │ │ │ ├── filesystem_file.cpp │ │ │ └── string_file.cpp │ │ ├── resource_impl.cpp │ │ ├── service_impl.cpp │ │ ├── service_with_resources_impl.cpp │ │ └── utilities │ │ │ ├── connection.cpp │ │ │ ├── json.cpp │ │ │ ├── os.cpp │ │ │ └── string.cpp │ ├── resource.cpp │ ├── resource_arguments.cpp │ ├── retdec-config.cmake.in │ ├── service.cpp │ ├── settings.cpp │ └── test.cpp └── tools │ ├── CMakeLists.txt │ ├── decompiler.cpp │ └── fileinfo.cpp └── tests ├── CMakeLists.txt └── retdec ├── CMakeLists.txt ├── analysis_arguments_tests.cpp ├── analysis_tests.cpp ├── decompilation_arguments_tests.cpp ├── decompilation_tests.cpp ├── decompiler_tests.cpp ├── exceptions_tests.cpp ├── file_mock.h ├── file_tests.cpp ├── fileinfo_tests.cpp ├── internal ├── connection_manager_mock.h ├── connection_manager_tests.cpp ├── connection_managers │ └── real_connection_manager_tests.cpp ├── connection_mock.h ├── connection_tests.cpp ├── connections │ └── real_connection_tests.cpp ├── files │ ├── filesystem_file_tests.cpp │ └── string_file_tests.cpp └── utilities │ ├── connection_tests.cpp │ ├── container_tests.cpp │ ├── json_tests.cpp │ ├── os_tests.cpp │ ├── smart_ptr_tests.cpp │ └── string_tests.cpp ├── resource_arguments_tests.cpp ├── settings_tests.cpp ├── test_tests.cpp └── test_utilities ├── tmp_file.cpp └── tmp_file.h /.gitignore: -------------------------------------------------------------------------------- 1 | /build* 2 | /install 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | dev 5 | --- 6 | 7 | * (nothing yet) 8 | 9 | 0.2 (2016-03-14) 10 | ---------------- 11 | 12 | * Added basic support for the [file-analyzing 13 | service](https://retdec.com/api/docs/fileinfo.html). Also added a sample tool 14 | that uses this service to analyze binary files (`fileinfo`). 15 | * Added basic support for the [test 16 | service](https://retdec.com/api/docs/test.html). It can be used to verify 17 | API-key authentications. 18 | * Added a new subclass of `ApiError`: `AuthError`. It is thrown when there is 19 | an authentication or authorization error. 20 | 21 | 0.1 (2015-12-06) 22 | ---------------- 23 | 24 | Initial release. 25 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## 2 | ## Project: retdec-cpp 3 | ## Copyright: (c) 2015 by Petr Zemek 4 | ## License: MIT, see the LICENSE file for more details 5 | ## 6 | ## The project's main CMake configuration file. 7 | ## 8 | 9 | cmake_minimum_required(VERSION 2.8) 10 | 11 | project(retdec-cpp CXX C) 12 | 13 | ## 14 | ## Options. 15 | ## 16 | 17 | option(RETDEC_DOC "Build public API documentation (requires Doxygen)." OFF) 18 | option(RETDEC_INTERNAL_DOC "Build also the internal parts of the API documentation." OFF) 19 | option(RETDEC_TOOLS "Build tools." OFF) 20 | option(RETDEC_COVERAGE "Build with code coverage support (requires GCC and lcov)." OFF) 21 | option(RETDEC_TESTS "Build tests." OFF) 22 | 23 | if(${RETDEC_INTERNAL_DOC}) 24 | set(RETDEC_DOC ON) 25 | endif() 26 | 27 | if(${RETDEC_COVERAGE}) 28 | set(RETDEC_TESTS ON) 29 | 30 | # The coverage currently works only for GCC builds. 31 | if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 32 | message(FATAL_ERROR "Code coverage support requires GCC to be used.") 33 | endif() 34 | endif() 35 | 36 | ## 37 | ## Paths. 38 | ## 39 | 40 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") 41 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 42 | set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install" CACHE PATH "default install path" FORCE) 43 | endif() 44 | set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin") 45 | set(INSTALL_DOC_DIR "${CMAKE_INSTALL_PREFIX}/doc") 46 | set(INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/include") 47 | set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") 48 | set(INSTALL_LIB_CMAKE_DIR "${INSTALL_LIB_DIR}/cmake") 49 | 50 | ## 51 | ## Dependencies. 52 | ## 53 | 54 | include(ExternalProject) 55 | 56 | # The default root directory for external projects. 57 | set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/third_party) 58 | 59 | # Threads 60 | find_package(Threads REQUIRED) 61 | 62 | # Boost 63 | find_package(Boost 1.55 COMPONENTS "filesystem" "system" "thread" REQUIRED) 64 | include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) 65 | # A workaround to link error "undefined reference to 66 | # `boost::filesystem::detail::copy_file()" when using Boost < 1.57 67 | # (https://www.robertnitsch.de/notes/cpp/cpp11_boost_filesystem_undefined_reference_copy_file). 68 | add_definitions(-DBOOST_NO_CXX11_SCOPED_ENUMS) 69 | 70 | # OpenSSL 71 | find_package(OpenSSL REQUIRED) 72 | include_directories(SYSTEM ${OPENSSL_INCLUDE_DIR}) 73 | 74 | # cpp-netlib 75 | find_package(CPP-NETLIB COMPONENTS "uri" "client-connections") 76 | if(NOT CPPNETLIB_FOUND) 77 | message(STATUS " --> cppnetlib will be built as an external project") 78 | ExternalProject_Add(cpp-netlib 79 | URL http://downloads.cpp-netlib.org/0.11.2/cpp-netlib-0.11.2-final.zip 80 | CMAKE_ARGS 81 | -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} 82 | -DCPP-NETLIB_BUILD_TESTS:BOOL=OFF 83 | -DCPP-NETLIB_BUILD_EXAMPLES:BOOL=OFF 84 | # Disable the install step. 85 | INSTALL_COMMAND "" 86 | # Wrap the download, configure and build steps in a script to log the 87 | # output. 88 | LOG_DOWNLOAD ON 89 | LOG_CONFIGURE ON 90 | LOG_BUILD ON 91 | ) 92 | ExternalProject_Get_Property(cpp-netlib source_dir) 93 | ExternalProject_Get_Property(cpp-netlib binary_dir) 94 | set(CPPNETLIB_INCLUDE_DIR "${source_dir}") 95 | set(CPPNETLIB_LIBRARY_DIR "${binary_dir}/libs/network/src") 96 | set(CPPNETLIB_LIBRARIES "cppnetlib-uri" "cppnetlib-client-connections") 97 | link_directories(${CPPNETLIB_LIBRARY_DIR}) 98 | endif() 99 | include_directories(SYSTEM ${CPPNETLIB_INCLUDE_DIR}) 100 | # Enable HTTPS. The following symbol has to be defined prior to including 101 | # cpp-netlib headers. 102 | add_definitions(-DBOOST_NETWORK_ENABLE_HTTPS) 103 | 104 | # json-cpp 105 | find_package(JsonCpp) 106 | if(NOT JsonCpp_FOUND) 107 | message(STATUS " --> JsonCpp will be built as an external project") 108 | ExternalProject_Add(json-cpp 109 | URL https://github.com/open-source-parsers/jsoncpp/archive/1.6.5.zip 110 | CMAKE_ARGS 111 | -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} 112 | -DJSONCPP_WITH_TESTS:BOOL=OFF 113 | # Disable the install step. 114 | INSTALL_COMMAND "" 115 | # Wrap the download, configure and build steps in a script to log the 116 | # output. 117 | LOG_DOWNLOAD ON 118 | LOG_CONFIGURE ON 119 | LOG_BUILD ON 120 | ) 121 | ExternalProject_Get_Property(json-cpp source_dir) 122 | ExternalProject_Get_Property(json-cpp binary_dir) 123 | set(JsonCpp_INCLUDE_DIR "${source_dir}/include") 124 | set(JsonCpp_LIBRARY_DIR "${binary_dir}/src/json_lib") 125 | set(JsonCpp_LIBRARY "jsoncpp") 126 | link_directories(${JsonCpp_LIBRARY_DIR}) 127 | endif() 128 | include_directories(SYSTEM ${JsonCpp_INCLUDE_DIR}) 129 | 130 | ## 131 | ## Includes. 132 | ## 133 | 134 | include_directories(include) 135 | 136 | ## 137 | ## Compiler options. 138 | ## 139 | 140 | if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 141 | # C++14 is required. 142 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -pedantic") 143 | 144 | # Abort compilation upon the first error. 145 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wfatal-errors") 146 | 147 | # Standard warning parameters. 148 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") 149 | 150 | # Enable additional warnings that are not included in -Wall and -Wextra 151 | # (according to `man gcc`). 152 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-align") 153 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-qual") 154 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wfloat-equal") 155 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast") 156 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wswitch-default") 157 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wuninitialized") 158 | 159 | # Compiler-specific warnings. 160 | if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 161 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wuseless-cast") 162 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wzero-as-null-pointer-constant") 163 | elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 164 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wconditional-uninitialized") 165 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wheader-hygiene") 166 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-literal-null-conversion") 167 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wreserved-id-macro") 168 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsometimes-uninitialized") 169 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunreachable-code") 170 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-exception-parameter") 171 | endif() 172 | endif() 173 | 174 | ## 175 | ## Code coverage. 176 | ## 177 | 178 | if(RETDEC_COVERAGE) 179 | # Enable code coverage. 180 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") 181 | 182 | # Build with debugging information to make the output meaningful. 183 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") 184 | 185 | # Disable optimizations to get the most accurate results. 186 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0") 187 | 188 | # Add a custom target to generate the code coverage. 189 | add_custom_target(coverage 190 | COMMENT "Running the tests and generating code coverage" 191 | COMMAND "${PROJECT_BINARY_DIR}/tests/retdec/retdec_tests" 192 | COMMAND mkdir -p "${PROJECT_BINARY_DIR}/coverage" 193 | COMMAND lcov --capture --no-external 194 | --directory include --directory "${PROJECT_BINARY_DIR}/include" 195 | --directory src --directory "${PROJECT_BINARY_DIR}/src" 196 | # Comment out the next line if you want to omit test code from the 197 | # coverage. 198 | --directory tests --directory "${PROJECT_BINARY_DIR}/tests" 199 | --output-file "${PROJECT_BINARY_DIR}/coverage/coverage.info" 200 | COMMAND genhtml --show-details --num-spaces 4 --demangle-cpp 201 | --legend --title "retdec-cpp code coverage" 202 | --output-directory "${PROJECT_BINARY_DIR}/coverage" 203 | "${PROJECT_BINARY_DIR}/coverage/coverage.info" 204 | WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" 205 | ) 206 | endif() 207 | 208 | ## 209 | ## Subdirectories. 210 | ## 211 | 212 | add_subdirectory(doc) 213 | add_subdirectory(include) 214 | add_subdirectory(src) 215 | add_subdirectory(tests) 216 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Petr Zemek and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | retdec-cpp 2 | ========== 3 | 4 | WARNING 5 | ------- 6 | 7 | The [retdec.com](https://retdec.com) decompilation service is to be disabled 8 | (see the [official 9 | announcement](https://retdec.com/news/?2018-06-07-New-Version-3-1)). This will 10 | render the library and tools in the present repository non-functional. I will 11 | keep the repository online in case it is helpful to anyone. 12 | 13 | Description 14 | ----------- 15 | 16 | A C++ library and tools providing easy access to the 17 | [retdec.com](https://retdec.com) decompilation service through their public 18 | [REST API](https://retdec.com/api/). 19 | 20 | Usage Example 21 | ------------- 22 | 23 | The following example creates a decompiler, starts a decompilation of the given 24 | binary file, and prints the decompiled C code to the standard output. 25 | 26 | ``` cpp 27 | #include 28 | #include 29 | 30 | using namespace retdec; 31 | 32 | int main(int argc, char **argv) { 33 | if (argc != 3) { 34 | std::cerr << "usage: " << argv[0] << " API-KEY FILE\n"; 35 | return 1; 36 | } 37 | 38 | try { 39 | Decompiler decompiler( 40 | Settings() 41 | .apiKey(argv[1]) 42 | ); 43 | auto decompilation = decompiler.runDecompilation( 44 | DecompilationArguments() 45 | .mode("bin") 46 | .inputFile(File::fromFilesystem(argv[2])) 47 | ); 48 | decompilation->waitUntilFinished(); 49 | std::cout << decompilation->getOutputHll(); 50 | return 0; 51 | } catch (const Error &ex) { 52 | std::cerr << "error: " << ex.what() << "\n"; 53 | return 1; 54 | } 55 | } 56 | ``` 57 | 58 | Status 59 | ------ 60 | 61 | The library currently provides very basic support of the 62 | [decompilation](https://retdec.com/api/docs/decompiler.html), 63 | [file-analyzing](https://retdec.com/api/docs/fileinfo.html), and 64 | [test](https://retdec.com/api/docs/test.html) services. 65 | 66 | Requirements 67 | ------------ 68 | 69 | To build the library and tools, you need: 70 | * A compiler supporting C++14. Supported compilers are: 71 | * [GCC](https://gcc.gnu.org/) (version >= 4.9) 72 | * [Clang](http://clang.llvm.org/) (version >= 3.5) 73 | * [MS Visual Studio](https://www.visualstudio.com/) (version 2015) 74 | * [CMake](https://cmake.org/) (version >= 2.8) 75 | * [Boost](http://www.boost.org/) (version >= 1.55) 76 | * [cpp-netlib](http://cpp-netlib.org/) (version >= 0.11) 77 | * [OpenSSL](https://www.openssl.org/) (version >= 1.0) 78 | * [JsonCpp](https://github.com/open-source-parsers/jsoncpp) (version >= 1.0) 79 | 80 | The [Boost](http://www.boost.org/) and [OpenSSL](https://www.openssl.org/) 81 | libraries have to be installed on your system. Other libraries are 82 | automatically downloaded and built if they are not present on your system. 83 | 84 | Build and Installation 85 | ---------------------- 86 | 87 | * Clone the repository or download the sources into a directory. Let's call the 88 | directory `retdec`. 89 | * `cd retdec` 90 | * `mkdir build && cd build` 91 | * `cmake ..` 92 | * `make && make install` 93 | 94 | You can pass additional parameters to `cmake`: 95 | * `-DRETDEC_DOC=ON` to build with API documentation (requires 96 | [Doxygen](http://www.doxygen.org/), disabled by default). 97 | * `-DRETDEC_TOOLS=ON` to build with tools (disabled by default). 98 | * `-DRETDEC_TESTS=ON` to build with unit tests (disabled by default). 99 | * `-DRETDEC_COVERAGE=ON` to build with code coverage support (requires 100 | [LCOV](http://ltp.sourceforge.net/coverage/lcov.php), disabled by default). 101 | * `-DCMAKE_BUILD_TYPE=Debug` to build with debugging information, which is 102 | useful during development. By default, the library is built in the 103 | `Release` mode. 104 | * `-DCMAKE_INSTALL_PREFIX:PATH=/opt/retdec` to set a custom installation path. 105 | 106 | You can force a specific version of the required libraries by passing the 107 | following parameters to `cmake`: 108 | * `-DBOOST_ROOT=$BOOST_DIR` 109 | * `-DCPPNETLIB_ROOT=$CPPNETLIB_DIR` 110 | * `-DOPENSSL_ROOT_DIR=$OPENSSL_DIR` 111 | * `-DJsonCpp_ROOT_DIR=$JSONCPP_DIR` 112 | 113 | The `make` call supports standard parameters, such as: 114 | * `-j N` to build the library in parallel using `N` processes. 115 | * `VERBOSE=1` to show verbose output when building the library. 116 | 117 | Use 118 | --- 119 | 120 | If you use [CMake](https://cmake.org/), you can incorporate the library into 121 | your project in the following way: 122 | 123 | ``` 124 | set(retdec_DIR "/path/to/installed/retdec/lib/cmake") 125 | find_package(retdec) 126 | include_directories(SYSTEM ${retdec_INCLUDE_DIRS}) 127 | 128 | add_executable(your_app your_app.cpp) 129 | target_link_libraries(your_app retdec) 130 | ``` 131 | 132 | API Documentation 133 | ----------------- 134 | 135 | The API documentation is available here: 136 | * [latest](https://projects.petrzemek.net/retdec-cpp/doc/) 137 | * [0.2](https://projects.petrzemek.net/retdec-cpp/doc/0.2/) 138 | * [0.1](https://projects.petrzemek.net/retdec-cpp/doc/0.1/) 139 | 140 | You can also generate it by yourself (pass `-DRETDEC_DOC=ON` to `cmake` and run 141 | `make doc`). 142 | 143 | License 144 | ------- 145 | 146 | Copyright (c) 2015 Petr Zemek () and contributors. 147 | 148 | Distributed under the MIT license. See the 149 | [`LICENSE`](https://github.com/s3rvac/retdec-cpp/blob/master/LICENSE) file for 150 | more details. 151 | 152 | Access from Other Languages 153 | --------------------------- 154 | 155 | If you want to access the [retdec.com](https://retdec.com) decompilation 156 | service from other languages, check out the following projects: 157 | 158 | * [retdec-python](https://github.com/s3rvac/retdec-python) - A library and 159 | tools for accessing the service from Python. 160 | * [retdec-rust](https://github.com/s3rvac/retdec-rust) - A library and 161 | tools for accessing the service from Rust. 162 | * [retdec-sh](https://github.com/s3rvac/retdec-sh) - Scripts for accessing the 163 | service from shell. 164 | -------------------------------------------------------------------------------- /cmake/FindCPP-NETLIB.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # From: https://github.com/Eyescale/CMake/ 3 | # Author: Grigori Chevtchenko , 2015 4 | # Licence: BSD 5 | # 6 | 7 | # 8 | # Copyright 2015 Grigori Chevtchenko 9 | # 10 | # Redistribution and use in source and binary forms, with or without 11 | # modification, are permitted provided that the following conditions are met: 12 | # 13 | # - Redistributions of source code must retain the above copyright notice, this 14 | # list of conditions and the following disclaimer. 15 | # - Redistributions in binary form must reproduce the above copyright notice, 16 | # this list of conditions and the following disclaimer in the documentation 17 | # and/or other materials provided with the distribution. 18 | # - Neither the name of Eyescale Software GmbH nor the names of its 19 | # contributors may be used to endorse or promote products derived from this 20 | # software without specific prior written permission. 21 | # 22 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 26 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | # POSSIBILITY OF SUCH DAMAGE. 33 | # 34 | # ============================================================================= 35 | # 36 | # CPPNETLIB 37 | # 38 | #============================================================================== 39 | # This module uses the following input variables: 40 | # 41 | # CPPNETLIB_ROOT - Path to the cpp-netlib module 42 | # 43 | # This module defines the following output variables: 44 | # 45 | # CPPNETLIB_FOUND - Was cppnetlib and all of the specified components found? 46 | # 47 | # CPPNETLIB_INCLUDE_DIRS - Where to find the headers 48 | # 49 | # CPPNETLIB_LIBRARIES - The cppnetlib libraries 50 | #============================================================================== 51 | # 52 | 53 | # Assume not found. 54 | set(CPPNETLIB_FOUND FALSE) 55 | set(CPPNETLIB_PATH) 56 | 57 | # Find headers 58 | find_path(CPPNETLIB_INCLUDE_DIR boost/network.hpp 59 | HINTS ${CPPNETLIB_ROOT}/include $ENV{CPPNETLIB_ROOT}/include 60 | ${COMMON_SOURCE_DIR}/cppnetlib ${CMAKE_SOURCE_DIR}/cppnetlib 61 | /usr/local/include 62 | /usr/include) 63 | 64 | if(CPPNETLIB_INCLUDE_DIR) 65 | set(CPPNETLIB_PATH "${CPPNETLIB_INCLUDE_DIR}/..") 66 | endif() 67 | 68 | # Find dynamic libraries 69 | if(CPPNETLIB_PATH) 70 | set(__libraries cppnetlib-client-connections 71 | cppnetlib-server-parsers 72 | cppnetlib-uri) 73 | 74 | foreach(__library ${__libraries}) 75 | if(TARGET ${__library}) 76 | list(APPEND CPPNETLIB_LIBRARIES ${__library}) 77 | set(CPPNETLIB_FOUND_SUBPROJECT ON) 78 | else() 79 | find_library(${__library} NAMES ${__library} 80 | HINTS ${CPPNETLIB_ROOT} $ENV{CPPNETLIB_ROOT} 81 | PATHS ${CPPNETLIB_PATH}/lib64 ${CPPNETLIB_PATH}/lib) 82 | list(APPEND CPPNETLIB_LIBRARIES ${${__library}}) 83 | endif() 84 | endforeach() 85 | mark_as_advanced(CPPNETLIB_LIBRARIES) 86 | endif() 87 | 88 | if(NOT cppnetlib_FIND_QUIETLY) 89 | set(_cppnetlib_output 1) 90 | endif() 91 | 92 | include(FindPackageHandleStandardArgs) 93 | find_package_handle_standard_args(cppnetlib DEFAULT_MSG 94 | CPPNETLIB_LIBRARIES 95 | CPPNETLIB_INCLUDE_DIR) 96 | 97 | if(CPPNETLIB_FOUND) 98 | set(CPPNETLIB_INCLUDE_DIRS ${CPPNETLIB_INCLUDE_DIR}) 99 | if(_cppnetlib_output ) 100 | message(STATUS "Found cppnetlib in ${CPPNETLIB_INCLUDE_DIR}:${CPPNETLIB_LIBRARIES}") 101 | endif() 102 | else() 103 | set(CPPNETLIB_FOUND) 104 | set(CPPNETLIB_INCLUDE_DIR) 105 | set(CPPNETLIB_INCLUDE_DIRS) 106 | set(CPPNETLIB_LIBRARIES) 107 | endif() 108 | -------------------------------------------------------------------------------- /cmake/FindGMock.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # From: https://github.com/triglav/cmake-findgmock 3 | # Author: Matej Svec, Copyright (c) 2011 4 | # Licence: MIT 5 | # 6 | 7 | # Locate the Google C++ Mocking Framework. 8 | # (This file is almost an identical copy of the original FindGTest.cmake file, 9 | # feel free to use it as it is or modify it for your own needs.) 10 | # 11 | # Defines the following variables: 12 | # 13 | # GMOCK_FOUND - Found the Google Testing framework 14 | # GMOCK_INCLUDE_DIRS - Include directories 15 | # 16 | # Also defines the library variables below as normal 17 | # variables. These contain debug/optimized keywords when 18 | # a debugging library is found. 19 | # 20 | # GMOCK_BOTH_LIBRARIES - Both libgmock & libgmock-main 21 | # GMOCK_LIBRARIES - libgmock 22 | # GMOCK_MAIN_LIBRARIES - libgmock-main 23 | # 24 | # Accepts the following variables as input: 25 | # 26 | # GMOCK_ROOT - (as a CMake or environment variable) 27 | # The root directory of the gmock install prefix 28 | # 29 | # GMOCK_MSVC_SEARCH - If compiling with MSVC, this variable can be set to 30 | # "MD" or "MT" to enable searching a gmock build tree 31 | # (defaults: "MD") 32 | # 33 | #----------------------- 34 | # Example Usage: 35 | # 36 | # find_package(GMock REQUIRED) 37 | # include_directories(${GMOCK_INCLUDE_DIRS}) 38 | # 39 | # add_executable(foo foo.cc) 40 | # target_link_libraries(foo ${GMOCK_BOTH_LIBRARIES}) 41 | # 42 | #============================================================================= 43 | # This file is released under the MIT licence: 44 | # 45 | # Copyright (c) 2011 Matej Svec 46 | # 47 | # Permission is hereby granted, free of charge, to any person obtaining a copy 48 | # of this software and associated documentation files (the "Software"), to 49 | # deal in the Software without restriction, including without limitation the 50 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 51 | # sell copies of the Software, and to permit persons to whom the Software is 52 | # furnished to do so, subject to the following conditions: 53 | # 54 | # The above copyright notice and this permission notice shall be included in 55 | # all copies or substantial portions of the Software. 56 | # 57 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 58 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 59 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 60 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 61 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 62 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 63 | # IN THE SOFTWARE. 64 | #============================================================================= 65 | 66 | 67 | function(_gmock_append_debugs _endvar _library) 68 | if(${_library} AND ${_library}_DEBUG) 69 | set(_output optimized ${${_library}} debug ${${_library}_DEBUG}) 70 | else() 71 | set(_output ${${_library}}) 72 | endif() 73 | set(${_endvar} ${_output} PARENT_SCOPE) 74 | endfunction() 75 | 76 | function(_gmock_find_library _name) 77 | find_library(${_name} 78 | NAMES ${ARGN} 79 | HINTS 80 | $ENV{GMOCK_ROOT} 81 | ${GMOCK_ROOT} 82 | PATH_SUFFIXES ${_gmock_libpath_suffixes} 83 | ) 84 | mark_as_advanced(${_name}) 85 | endfunction() 86 | 87 | 88 | if(NOT DEFINED GMOCK_MSVC_SEARCH) 89 | set(GMOCK_MSVC_SEARCH MD) 90 | endif() 91 | 92 | set(_gmock_libpath_suffixes lib) 93 | if(MSVC) 94 | if(GMOCK_MSVC_SEARCH STREQUAL "MD") 95 | list(APPEND _gmock_libpath_suffixes 96 | msvc/gmock-md/Debug 97 | msvc/gmock-md/Release) 98 | elseif(GMOCK_MSVC_SEARCH STREQUAL "MT") 99 | list(APPEND _gmock_libpath_suffixes 100 | msvc/gmock/Debug 101 | msvc/gmock/Release) 102 | endif() 103 | endif() 104 | 105 | find_path(GMOCK_INCLUDE_DIR gmock/gmock.h 106 | HINTS 107 | $ENV{GMOCK_ROOT}/include 108 | ${GMOCK_ROOT}/include 109 | ) 110 | mark_as_advanced(GMOCK_INCLUDE_DIR) 111 | 112 | if(MSVC AND GMOCK_MSVC_SEARCH STREQUAL "MD") 113 | # The provided /MD project files for Google Mock add -md suffixes to the 114 | # library names. 115 | _gmock_find_library(GMOCK_LIBRARY gmock-md gmock) 116 | _gmock_find_library(GMOCK_LIBRARY_DEBUG gmock-mdd gmockd) 117 | _gmock_find_library(GMOCK_MAIN_LIBRARY gmock_main-md gmock_main) 118 | _gmock_find_library(GMOCK_MAIN_LIBRARY_DEBUG gmock_main-mdd gmock_maind) 119 | else() 120 | _gmock_find_library(GMOCK_LIBRARY gmock) 121 | _gmock_find_library(GMOCK_LIBRARY_DEBUG gmockd) 122 | _gmock_find_library(GMOCK_MAIN_LIBRARY gmock_main) 123 | _gmock_find_library(GMOCK_MAIN_LIBRARY_DEBUG gmock_maind) 124 | endif() 125 | 126 | include(FindPackageHandleStandardArgs) 127 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMock DEFAULT_MSG GMOCK_LIBRARY GMOCK_INCLUDE_DIR GMOCK_MAIN_LIBRARY) 128 | 129 | if(GMOCK_FOUND) 130 | set(GMOCK_INCLUDE_DIRS ${GMOCK_INCLUDE_DIR}) 131 | _gmock_append_debugs(GMOCK_LIBRARIES GMOCK_LIBRARY) 132 | _gmock_append_debugs(GMOCK_MAIN_LIBRARIES GMOCK_MAIN_LIBRARY) 133 | set(GMOCK_BOTH_LIBRARIES ${GMOCK_LIBRARIES} ${GMOCK_MAIN_LIBRARIES}) 134 | endif() 135 | -------------------------------------------------------------------------------- /cmake/FindJsonCpp.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # From: https://github.com/sourcey/libsourcey 3 | # Author: Kam Low 4 | # Modified By: Petr Zemek 5 | # Licence: LGPL 6 | # 7 | 8 | ######################################################################## 9 | # Cmake module for finding JsonCpp 10 | # 11 | # The following variables are used as inputs: 12 | # 13 | # JsonCpp_ROOT 14 | # 15 | # The following variables will be defined: 16 | # 17 | # JsonCpp_FOUND 18 | # JsonCpp_INCLUDE_DIR 19 | # JsonCpp_LIBRARY 20 | # 21 | 22 | # ---------------------------------------------------------------------- 23 | # Find JsonCpp include path 24 | # ---------------------------------------------------------------------- 25 | FIND_PATH(JsonCpp_INCLUDE_DIR 26 | NAMES 27 | json/json.h 28 | HINTS 29 | ${JsonCpp_ROOT_DIR}/include 30 | ) 31 | 32 | # ---------------------------------------------------------------------- 33 | # Find JsonCpp library 34 | # ---------------------------------------------------------------------- 35 | if(WIN32 AND MSVC) 36 | 37 | find_library(JsonCpp_DEBUG_LIBRARY 38 | NAMES 39 | jsoncppd 40 | HINTS 41 | ${JsonCpp_ROOT_DIR}/lib 42 | ) 43 | 44 | find_library(JsonCpp_RELEASE_LIBRARY 45 | NAMES 46 | jsoncpp 47 | HINTS 48 | ${JsonCpp_ROOT_DIR}/lib 49 | ) 50 | 51 | if(JsonCpp_DEBUG_LIBRARY OR JsonCpp_RELEASE_LIBRARY) 52 | if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) 53 | if (JsonCpp_RELEASE_LIBRARY) 54 | list(APPEND JsonCpp_LIBRARY "optimized" ${JsonCpp_RELEASE_LIBRARY}) 55 | endif() 56 | if (JsonCpp_DEBUG_LIBRARY) 57 | list(APPEND JsonCpp_LIBRARY "debug" ${JsonCpp_DEBUG_LIBRARY}) 58 | endif() 59 | else() 60 | if (JsonCpp_RELEASE_LIBRARY) 61 | list(APPEND JsonCpp_LIBRARY ${JsonCpp_RELEASE_LIBRARY}) 62 | elseif (JsonCpp_DEBUG_LIBRARY) 63 | list(APPEND JsonCpp_LIBRARY ${JsonCpp_DEBUG_LIBRARY}) 64 | endif() 65 | endif() 66 | mark_as_advanced(JsonCpp_DEBUG_LIBRARY JsonCpp_RELEASE_LIBRARY) 67 | endif() 68 | 69 | else() 70 | 71 | find_library(JsonCpp_LIBRARY 72 | NAMES 73 | jsoncpp 74 | libjsoncpp 75 | HINTS 76 | ${JsonCpp_ROOT_DIR}/lib 77 | ) 78 | 79 | endif() 80 | 81 | if(JsonCpp_LIBRARY AND JsonCpp_INCLUDE_DIR) 82 | set(JsonCpp_FOUND 1) 83 | mark_as_advanced(JsonCpp_LIBRARY JsonCpp_INCLUDE_DIR) 84 | else() 85 | set(JsonCpp_FOUND 0) 86 | endif() 87 | 88 | # Display status. 89 | if(NOT JsonCpp_FOUND) 90 | if(JsonCpp_FIND_REQUIRED) 91 | message(FATAL_ERROR "JsonCpp was not found. Please build dependencies first, or specify the path manually.") 92 | endif() 93 | endif() 94 | 95 | # Adhere to standards. 96 | include(FindPackageHandleStandardArgs) 97 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(JsonCpp JsonCpp_INCLUDE_DIR JsonCpp_LIBRARY) 98 | -------------------------------------------------------------------------------- /doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## 2 | ## Project: retdec-cpp 3 | ## Copyright: (c) 2015 by Petr Zemek and contributors 4 | ## License: MIT, see the LICENSE file for more details 5 | ## 6 | ## CMake configuration file for the API documentation. 7 | ## 8 | 9 | if(NOT RETDEC_DOC) 10 | return() 11 | endif() 12 | 13 | find_package(Doxygen REQUIRED) 14 | 15 | set(DOXYGEN_CFG_IN "doxygen.in") 16 | set(DOXYGEN_CFG "${CMAKE_CURRENT_BINARY_DIR}/doxygen.cfg") 17 | # The trailing '/' after html is significant (otherwise, the files would be 18 | # installed into ${INSTALL_DOC_DIR}/html instead of ${INSTALL_DOC_DIR}). 19 | set(DOXYGEN_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/html/") 20 | 21 | # Properly configure the Doxygen configuration file. 22 | if(RETDEC_INTERNAL_DOC) 23 | # Generate also internal parts of the documentation. 24 | set(DOXYGEN_WARNINGS "YES") 25 | set(DOXYGEN_EXTRACT_PRIVATE "YES") 26 | set(DOXYGEN_EXTRACT_LOCAL_CLASSES "YES") 27 | set(DOXYGEN_INTERNAL_DOCS "YES") 28 | set(DOXYGEN_EXCLUDE_PATTERNS "") 29 | set(DOXYGEN_EXCLUDE_SYMBOLS "") 30 | set(DOXYGEN_ENABLED_SECTIONS "internal") 31 | else() 32 | # Hide internal parts of the documentation. 33 | set(DOXYGEN_WARNINGS "NO") 34 | set(DOXYGEN_EXTRACT_PRIVATE "NO") 35 | set(DOXYGEN_EXTRACT_LOCAL_CLASSES "NO") 36 | set(DOXYGEN_INTERNAL_DOCS "NO") 37 | set(DOXYGEN_EXCLUDE_PATTERNS "*/internal/*") 38 | set(DOXYGEN_EXCLUDE_SYMBOLS "internal") 39 | set(DOXYGEN_ENABLED_SECTIONS "") 40 | endif() 41 | configure_file("${DOXYGEN_CFG_IN}" "${DOXYGEN_CFG}" @ONLY) 42 | 43 | # Add a target to generate the documentation by running Doxygen. 44 | add_custom_target(doc ALL 45 | COMMAND ${DOXYGEN_EXECUTABLE} "${DOXYGEN_CFG}" 46 | SOURCES "${DOXYGEN_CFG}" 47 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 48 | COMMENT "Generating API documentation with Doxygen" VERBATIM 49 | ) 50 | 51 | # Cleanup. 52 | set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${DOXYGEN_OUTPUT_DIR}") 53 | 54 | install(DIRECTORY "${DOXYGEN_OUTPUT_DIR}" DESTINATION "${INSTALL_DOC_DIR}/retdec") 55 | -------------------------------------------------------------------------------- /doc/doxygen.extra.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Project: retdec-cpp 3 | * Copyright: (c) 2015 by Petr Zemek and contributors 4 | * License: MIT, see the LICENSE file for more details 5 | * 6 | * Custom CSS rules for the API documentation. 7 | */ 8 | 9 | /* Use a smaller font for the section headings. */ 10 | h1 { 11 | font-size: 140%; 12 | } 13 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## 2 | ## Project: retdec-cpp 3 | ## Copyright: (c) 2015 by Petr Zemek and contributors 4 | ## License: MIT, see the LICENSE file for more details 5 | ## 6 | ## CMake configuration file for the include files. 7 | ## 8 | 9 | set(PUBLIC_INCLUDES 10 | retdec/analysis.h 11 | retdec/analysis_arguments.h 12 | retdec/decompilation.h 13 | retdec/decompilation_arguments.h 14 | retdec/decompiler.h 15 | retdec/exceptions.h 16 | retdec/file.h 17 | retdec/fileinfo.h 18 | retdec/fwd_decls.h 19 | retdec/resource.h 20 | retdec/resource_arguments.h 21 | retdec/retdec.h 22 | retdec/service.h 23 | retdec/settings.h 24 | retdec/test.h 25 | ) 26 | 27 | install(FILES ${PUBLIC_INCLUDES} DESTINATION "${INSTALL_INCLUDE_DIR}/retdec") 28 | -------------------------------------------------------------------------------- /include/retdec/analysis.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/analysis.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Representation of an analysis. 6 | /// 7 | 8 | #ifndef RETDEC_ANALYSIS_H 9 | #define RETDEC_ANALYSIS_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "retdec/resource.h" 16 | 17 | namespace retdec { 18 | 19 | class File; 20 | 21 | namespace internal { 22 | 23 | class Connection; 24 | class AnalysisImpl; 25 | 26 | } // namespace internal 27 | 28 | /// 29 | /// Representation of an analysis. 30 | /// 31 | class Analysis: public Resource { 32 | public: 33 | /// 34 | /// What should the waiting member function do when an analysis fails? 35 | /// 36 | enum class OnError { 37 | Throw, ///< Throw AnalysisError when an analysis fails. 38 | NoThrow ///< Do not throw AnalysisError when an analysis fails. 39 | }; 40 | 41 | public: 42 | /// @cond internal 43 | Analysis(const std::string &id, 44 | const std::shared_ptr<::retdec::internal::Connection> &conn); 45 | /// @endcond 46 | virtual ~Analysis() override; 47 | 48 | /// @name Waiting For Analysis To Finish 49 | /// @{ 50 | void waitUntilFinished(OnError onError = OnError::Throw); 51 | /// @} 52 | 53 | /// @name Obtaining Outputs 54 | /// @{ 55 | std::shared_ptr getOutputAsFile(); 56 | std::string getOutput(); 57 | /// @} 58 | 59 | private: 60 | internal::AnalysisImpl *impl() noexcept; 61 | const internal::AnalysisImpl *impl() const noexcept; 62 | }; 63 | 64 | } // namespace retdec 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /include/retdec/analysis_arguments.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/analysis_arguments.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Arguments for analyses. 6 | /// 7 | 8 | #ifndef RETDEC_ANALYSIS_ARGUMENTS_H 9 | #define RETDEC_ANALYSIS_ARGUMENTS_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "retdec/resource_arguments.h" 16 | 17 | namespace retdec { 18 | 19 | /// 20 | /// Arguments for analyses. 21 | /// 22 | class AnalysisArguments: public ResourceArguments { 23 | public: 24 | /// @name Construction, Assignment, and Destruction 25 | /// @{ 26 | AnalysisArguments(); 27 | AnalysisArguments(const AnalysisArguments &other); 28 | AnalysisArguments(AnalysisArguments &&other); 29 | AnalysisArguments &operator=(const AnalysisArguments &other); 30 | AnalysisArguments &operator=(AnalysisArguments &&other); 31 | ~AnalysisArguments(); 32 | /// @} 33 | 34 | /// @name Verbose 35 | /// @{ 36 | AnalysisArguments &verbose(const std::string &verbose); 37 | AnalysisArguments withVerbose(const std::string &verbose) const; 38 | bool hasVerbose() const; 39 | std::string verbose() const; 40 | /// @} 41 | 42 | /// @name Input File 43 | /// @{ 44 | AnalysisArguments &inputFile(const std::shared_ptr &file); 45 | AnalysisArguments withInputFile(const std::shared_ptr &file) const; 46 | bool hasInputFile() const; 47 | std::shared_ptr inputFile() const; 48 | /// @} 49 | 50 | /// @name Generic Access To Arguments 51 | /// @{ 52 | using ResourceArguments::argument; 53 | AnalysisArguments &argument(const std::string &id, 54 | const std::string &value); 55 | AnalysisArguments withArgument(const std::string &id, 56 | const std::string &value) const; 57 | /// @} 58 | 59 | /// @name Generic Access To Files 60 | /// @{ 61 | using ResourceArguments::file; 62 | AnalysisArguments &file(const std::string &id, 63 | const std::shared_ptr &file); 64 | AnalysisArguments withFile(const std::string &id, 65 | const std::shared_ptr &file) const; 66 | /// @} 67 | }; 68 | 69 | } // namespace retdec 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /include/retdec/decompilation.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/decompilation.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Representation of a decompilation. 6 | /// 7 | 8 | #ifndef RETDEC_DECOMPILATION_H 9 | #define RETDEC_DECOMPILATION_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "retdec/resource.h" 16 | 17 | namespace retdec { 18 | 19 | class File; 20 | 21 | namespace internal { 22 | 23 | class Connection; 24 | class DecompilationImpl; 25 | 26 | } // namespace internal 27 | 28 | /// 29 | /// Representation of a decompilation. 30 | /// 31 | class Decompilation: public Resource { 32 | public: 33 | /// Type of a callback for waitUntilFinished(). 34 | using Callback = std::function; 35 | 36 | /// 37 | /// What should the waiting member functions do when a decompilation 38 | /// fails? 39 | /// 40 | enum class OnError { 41 | Throw, ///< Throw DecompilationError when a decompilation fails. 42 | NoThrow ///< Do not throw DecompilationError when a decompilation fails. 43 | }; 44 | 45 | public: 46 | /// @cond internal 47 | Decompilation(const std::string &id, 48 | const std::shared_ptr<::retdec::internal::Connection> &conn); 49 | /// @endcond 50 | virtual ~Decompilation() override; 51 | 52 | /// @name Querying 53 | /// @{ 54 | int getCompletion(); 55 | int getCompletion() const noexcept; 56 | /// @} 57 | 58 | /// @name Waiting For Decompilation To Finish 59 | /// @{ 60 | void waitUntilFinished(OnError onError = OnError::Throw); 61 | void waitUntilFinished(const Callback &callback, 62 | OnError onError = OnError::Throw); 63 | /// @} 64 | 65 | /// @name Obtaining Outputs 66 | /// @{ 67 | std::shared_ptr getOutputHllFile(); 68 | std::string getOutputHll(); 69 | /// @} 70 | 71 | private: 72 | internal::DecompilationImpl *impl() noexcept; 73 | const internal::DecompilationImpl *impl() const noexcept; 74 | }; 75 | 76 | } // namespace retdec 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /include/retdec/decompilation_arguments.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/decompilation_arguments.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Arguments for decompilations. 6 | /// 7 | 8 | #ifndef RETDEC_DECOMPILATION_ARGUMENTS_H 9 | #define RETDEC_DECOMPILATION_ARGUMENTS_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "retdec/resource_arguments.h" 16 | 17 | namespace retdec { 18 | 19 | /// 20 | /// Arguments for decompilations. 21 | /// 22 | class DecompilationArguments: public ResourceArguments { 23 | public: 24 | /// @name Construction, Assignment, and Destruction 25 | /// @{ 26 | DecompilationArguments(); 27 | DecompilationArguments(const DecompilationArguments &other); 28 | DecompilationArguments(DecompilationArguments &&other); 29 | DecompilationArguments &operator=(const DecompilationArguments &other); 30 | DecompilationArguments &operator=(DecompilationArguments &&other); 31 | ~DecompilationArguments(); 32 | /// @} 33 | 34 | /// @name Mode 35 | /// @{ 36 | DecompilationArguments &mode(const std::string &mode); 37 | DecompilationArguments withMode(const std::string &mode) const; 38 | bool hasMode() const; 39 | std::string mode() const; 40 | /// @} 41 | 42 | /// @name Selective Decompilation: Ranges 43 | /// @{ 44 | DecompilationArguments &selDecompRanges(const std::string &ranges); 45 | DecompilationArguments withSelDecompRanges(const std::string &ranges); 46 | bool hasSelDecompRanges() const; 47 | std::string selDecompRanges() const; 48 | /// @} 49 | 50 | /// @name Selective Decompilation: Decoding 51 | /// @{ 52 | DecompilationArguments &selDecompDecoding(const std::string &decoding); 53 | DecompilationArguments withSelDecompDecoding(const std::string &decoding); 54 | bool hasSelDecompDecoding() const; 55 | std::string selDecompDecoding() const; 56 | /// @} 57 | 58 | /// @name Files: Input 59 | /// @{ 60 | DecompilationArguments &inputFile(const std::shared_ptr &file); 61 | DecompilationArguments withInputFile(const std::shared_ptr &file) const; 62 | bool hasInputFile() const; 63 | std::shared_ptr inputFile() const; 64 | /// @} 65 | 66 | /// @name Generic Access To Arguments 67 | /// @{ 68 | using ResourceArguments::argument; 69 | DecompilationArguments &argument(const std::string &id, 70 | const std::string &value); 71 | DecompilationArguments withArgument(const std::string &id, 72 | const std::string &value) const; 73 | /// @} 74 | 75 | /// @name Generic Access To Files 76 | /// @{ 77 | using ResourceArguments::file; 78 | DecompilationArguments &file(const std::string &id, 79 | const std::shared_ptr &file); 80 | DecompilationArguments withFile(const std::string &id, 81 | const std::shared_ptr &file) const; 82 | /// @} 83 | }; 84 | 85 | } // namespace retdec 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /include/retdec/decompiler.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/decompiler.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Runner of decompilations. 6 | /// 7 | 8 | #ifndef RETDEC_DECOMPILER_H 9 | #define RETDEC_DECOMPILER_H 10 | 11 | #include 12 | 13 | #include "retdec/service.h" 14 | 15 | namespace retdec { 16 | 17 | class Decompilation; 18 | class DecompilationArguments; 19 | class Settings; 20 | 21 | namespace internal { 22 | 23 | class DecompilerImpl; 24 | class ConnectionManager; 25 | 26 | } // namespace internal 27 | 28 | /// 29 | /// Runner of decompilations. 30 | /// 31 | class Decompiler: public Service { 32 | public: 33 | /// @name Construction and Destruction 34 | /// @{ 35 | Decompiler(const Settings &settings); 36 | /// @cond internal 37 | Decompiler(const Settings &settings, 38 | const std::shared_ptr<::retdec::internal::ConnectionManager> &connectionManager); 39 | /// @endcond 40 | virtual ~Decompiler() override; 41 | /// @} 42 | 43 | /// @name Decompilations 44 | /// @{ 45 | std::unique_ptr runDecompilation( 46 | const DecompilationArguments &args); 47 | /// @} 48 | 49 | private: 50 | internal::DecompilerImpl *impl() noexcept; 51 | const internal::DecompilerImpl *impl() const noexcept; 52 | }; 53 | 54 | } // namespace retdec 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /include/retdec/exceptions.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/exceptions.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Exceptions. 6 | /// 7 | 8 | #ifndef RETDEC_EXCEPTIONS_H 9 | #define RETDEC_EXCEPTIONS_H 10 | 11 | #include 12 | #include 13 | 14 | namespace retdec { 15 | 16 | /// 17 | /// Base class of custom exceptions thrown by the library. 18 | /// 19 | class Error: public std::runtime_error { 20 | public: 21 | using std::runtime_error::runtime_error; 22 | }; 23 | 24 | /// 25 | /// Exception thrown when there is an I/O error. 26 | /// 27 | class IoError: public Error { 28 | public: 29 | using Error::Error; 30 | }; 31 | 32 | /// 33 | /// Exception thrown when there is a filesystem error. 34 | /// 35 | class FilesystemError: public IoError { 36 | public: 37 | using IoError::IoError; 38 | }; 39 | 40 | /// 41 | /// Exception thrown when there is a connection error. 42 | /// 43 | class ConnectionError: public IoError { 44 | public: 45 | using IoError::IoError; 46 | }; 47 | 48 | /// 49 | /// Exception thrown when the API is used incorrectly. 50 | /// 51 | class ApiError: public Error { 52 | public: 53 | ApiError(int code, const std::string &message, 54 | const std::string &description = ""); 55 | 56 | int getCode() const noexcept; 57 | std::string getMessage() const; 58 | std::string getDescription() const; 59 | 60 | private: 61 | /// Error code. 62 | const int code; 63 | 64 | /// Short message describing the error. 65 | const std::string message; 66 | 67 | /// Full description of the error. 68 | const std::string description; 69 | }; 70 | 71 | /// 72 | /// Exception thrown when there is an authentication or authorization error. 73 | /// 74 | class AuthError: public ApiError { 75 | public: 76 | using ApiError::ApiError; 77 | }; 78 | 79 | /// 80 | /// Base class of resource exceptions. 81 | /// 82 | class ResourceError: public Error { 83 | public: 84 | using Error::Error; 85 | }; 86 | 87 | /// 88 | /// Exception thrown when a decompilation fails. 89 | /// 90 | class DecompilationError: public ResourceError { 91 | public: 92 | using ResourceError::ResourceError; 93 | }; 94 | 95 | /// 96 | /// Exception thrown when an analysis fails. 97 | /// 98 | class AnalysisError: public ResourceError { 99 | public: 100 | using ResourceError::ResourceError; 101 | }; 102 | 103 | } // namespace retdec 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /include/retdec/file.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/file.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Base class and factory for file representations. 6 | /// 7 | 8 | #ifndef RETDEC_FILE_H 9 | #define RETDEC_FILE_H 10 | 11 | #include 12 | #include 13 | 14 | namespace retdec { 15 | 16 | /// 17 | /// Base class and factory for files. 18 | /// 19 | class File { 20 | public: 21 | virtual ~File() = 0; 22 | 23 | virtual std::string getName() const = 0; 24 | virtual std::string getContent() = 0; 25 | virtual void saveCopyTo(const std::string &directoryPath) = 0; 26 | virtual void saveCopyTo(const std::string &directoryPath, 27 | const std::string &name) = 0; 28 | 29 | static std::unique_ptr fromContentWithName( 30 | const std::string &content, const std::string &name); 31 | static std::unique_ptr fromFilesystem(const std::string &path); 32 | static std::unique_ptr fromFilesystemWithOtherName( 33 | const std::string &path, const std::string &name); 34 | 35 | /// @name Disabled 36 | /// @{ 37 | File(const File &) = delete; 38 | File(File &&) = delete; 39 | File &operator=(const File &) = delete; 40 | File &operator=(File &&) = delete; 41 | /// @} 42 | 43 | protected: 44 | File(); 45 | }; 46 | 47 | } // namespace retdec 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/retdec/fileinfo.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/fileinfo.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Runner of analyses. 6 | /// 7 | 8 | #ifndef RETDEC_FILEINFO_H 9 | #define RETDEC_FILEINFO_H 10 | 11 | #include 12 | 13 | #include "retdec/service.h" 14 | 15 | namespace retdec { 16 | 17 | class Analysis; 18 | class AnalysisArguments; 19 | class Settings; 20 | 21 | namespace internal { 22 | 23 | class ConnectionManager; 24 | class FileinfoImpl; 25 | 26 | } // namespace internal 27 | 28 | /// 29 | /// Runner of analyses. 30 | /// 31 | class Fileinfo: public Service { 32 | public: 33 | /// @name Construction and Destruction 34 | /// @{ 35 | Fileinfo(const Settings &settings); 36 | /// @cond internal 37 | Fileinfo(const Settings &settings, 38 | const std::shared_ptr<::retdec::internal::ConnectionManager> &connectionManager); 39 | /// @endcond 40 | virtual ~Fileinfo() override; 41 | /// @} 42 | 43 | /// @name Analyses 44 | /// @{ 45 | std::unique_ptr runAnalysis(const AnalysisArguments &args); 46 | /// @} 47 | 48 | private: 49 | internal::FileinfoImpl *impl() noexcept; 50 | const internal::FileinfoImpl *impl() const noexcept; 51 | }; 52 | 53 | } // namespace retdec 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /include/retdec/fwd_decls.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file fwd_decls.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Header file containing forward declarations for classes in the 6 | /// library. 7 | /// 8 | /// This header file contains declarations of top-level classes provided by the 9 | /// library for clients to use. 10 | /// 11 | 12 | #ifndef RETDEC_FWD_DECLS_H 13 | #define RETDEC_FWD_DECLS_H 14 | 15 | namespace retdec { 16 | 17 | class Analysis; 18 | class AnalysisArguments; 19 | class AnalysisError; 20 | class ApiError; 21 | class AuthError; 22 | class Decompilation; 23 | class DecompilationArguments; 24 | class DecompilationError; 25 | class Decompiler; 26 | class Error; 27 | class File; 28 | class Fileinfo; 29 | class FilesystemError; 30 | class IoError; 31 | class Resource; 32 | class ResourceArguments; 33 | class Service; 34 | class Settings; 35 | 36 | } // namespace retdec 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /include/retdec/internal/connection.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connection.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Base class of connections to the API. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_CONNECTION_H 9 | #define RETDEC_INTERNAL_CONNECTION_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace Json { 18 | 19 | class Value; 20 | 21 | } // namespace Json 22 | 23 | namespace retdec { 24 | 25 | class File; 26 | 27 | namespace internal { 28 | 29 | /// 30 | /// Base class of connections to the API. 31 | /// 32 | class Connection { 33 | public: 34 | /// 35 | /// Base class of responses returned from requests. 36 | /// 37 | class Response { 38 | public: 39 | virtual ~Response() = 0; 40 | 41 | virtual int statusCode() const = 0; 42 | virtual std::string statusMessage() const = 0; 43 | virtual std::string body() const = 0; 44 | virtual Json::Value bodyAsJson() const = 0; 45 | virtual std::unique_ptr bodyAsFile() const = 0; 46 | 47 | protected: 48 | Response(); 49 | }; 50 | 51 | /// URL. 52 | using Url = std::string; 53 | 54 | /// Name of an argument. 55 | using ArgumentName = std::string; 56 | 57 | /// Value of an argument. 58 | using ArgumentValue = std::string; 59 | 60 | /// Argument passed to a request. 61 | using RequestArgument = std::pair; 62 | 63 | /// Arguments passed to a request. 64 | using RequestArguments = std::vector; 65 | 66 | /// Name of a file argument. 67 | using FileArgumentName = std::string; 68 | 69 | /// Files passed to a request. 70 | using RequestFiles = std::map>; 71 | 72 | public: 73 | virtual ~Connection() = 0; 74 | 75 | virtual Url getApiUrl() const = 0; 76 | 77 | virtual std::unique_ptr sendGetRequest(const Url &url) = 0; 78 | virtual std::unique_ptr sendGetRequest(const Url &url, 79 | const RequestArguments &args) = 0; 80 | virtual std::unique_ptr sendPostRequest(const Url &url, 81 | const RequestArguments &args, const RequestFiles &files) = 0; 82 | 83 | protected: 84 | Connection(); 85 | }; 86 | 87 | } // namespace internal 88 | } // namespace retdec 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /include/retdec/internal/connection_manager.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connection_manager.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Base class of managers of connections to the API. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_CONNECTION_MANAGER_H 9 | #define RETDEC_INTERNAL_CONNECTION_MANAGER_H 10 | 11 | #include 12 | 13 | namespace retdec { 14 | 15 | class Settings; 16 | 17 | namespace internal { 18 | 19 | class Connection; 20 | 21 | /// 22 | /// Base class of managers of connections to the API. 23 | /// 24 | class ConnectionManager { 25 | public: 26 | virtual ~ConnectionManager() = 0; 27 | 28 | virtual std::shared_ptr newConnection(const Settings &settings) = 0; 29 | 30 | protected: 31 | ConnectionManager(); 32 | }; 33 | 34 | } // namespace internal 35 | } // namespace retdec 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/retdec/internal/connection_managers/real_connection_manager.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connection_managers/real_connection_manager.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Manager of connections to the API. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_CONNECTION_MANAGERS_REAL_CONNECTION_MANAGER_H 9 | #define RETDEC_INTERNAL_CONNECTION_MANAGERS_REAL_CONNECTION_MANAGER_H 10 | 11 | #include "retdec/internal/connection_manager.h" 12 | 13 | namespace retdec { 14 | namespace internal { 15 | 16 | /// 17 | /// Manager of connections to the API. 18 | /// 19 | class RealConnectionManager: public ConnectionManager { 20 | public: 21 | RealConnectionManager(); 22 | virtual ~RealConnectionManager() override; 23 | 24 | virtual std::shared_ptr newConnection( 25 | const Settings &settings) override; 26 | }; 27 | 28 | } // namespace internal 29 | } // namespace retdec 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/retdec/internal/connections/real_connection.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connections/real_connection.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Connection to the API. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_CONNECTIONS_REAL_CONNECTION_H 9 | #define RETDEC_INTERNAL_CONNECTIONS_REAL_CONNECTION_H 10 | 11 | #include 12 | 13 | #include "retdec/internal/connection.h" 14 | 15 | namespace retdec { 16 | 17 | class Settings; 18 | 19 | namespace internal { 20 | 21 | /// 22 | /// Connection to the API. 23 | /// 24 | class RealConnection: public Connection { 25 | public: 26 | RealConnection(const Settings &settings); 27 | virtual ~RealConnection() override; 28 | 29 | virtual Url getApiUrl() const override; 30 | 31 | virtual std::unique_ptr sendGetRequest(const Url &url) override; 32 | virtual std::unique_ptr sendGetRequest(const Url &url, 33 | const RequestArguments &args) override; 34 | virtual std::unique_ptr sendPostRequest(const Url &url, 35 | const RequestArguments &args, const RequestFiles &files) override; 36 | 37 | private: 38 | struct Impl; 39 | /// Private implementation. 40 | std::unique_ptr impl; 41 | }; 42 | 43 | } // namespace internal 44 | } // namespace retdec 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/retdec/internal/files/filesystem_file.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/files/filesystem_file.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief File stored in a filesystem. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_FILES_FILESYSTEM_FILE_H 9 | #define RETDEC_INTERNAL_FILES_FILESYSTEM_FILE_H 10 | 11 | #include 12 | 13 | #include "retdec/file.h" 14 | 15 | namespace retdec { 16 | namespace internal { 17 | 18 | /// 19 | /// File stored in a filesystem. 20 | /// 21 | class FilesystemFile: public File { 22 | public: 23 | explicit FilesystemFile(const std::string &path); 24 | FilesystemFile(std::string path, std::string name); 25 | virtual ~FilesystemFile() override; 26 | 27 | virtual std::string getName() const override; 28 | virtual std::string getContent() override; 29 | virtual void saveCopyTo(const std::string &directoryPath) override; 30 | virtual void saveCopyTo(const std::string &directoryPath, 31 | const std::string &name) override; 32 | 33 | private: 34 | /// Path to the file in a filesystem. 35 | std::string path; 36 | 37 | /// Name of the file to be used. 38 | std::string name; 39 | }; 40 | 41 | } // namespace internal 42 | } // namespace retdec 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /include/retdec/internal/files/string_file.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/files/string_file.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief File storing its content in a string. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_FILES_STRING_FILE_H 9 | #define RETDEC_INTERNAL_FILES_STRING_FILE_H 10 | 11 | #include 12 | 13 | #include "retdec/file.h" 14 | 15 | namespace retdec { 16 | namespace internal { 17 | 18 | /// 19 | /// File storing its content in a string. 20 | /// 21 | class StringFile: public File { 22 | public: 23 | explicit StringFile(std::string content); 24 | StringFile(std::string content, std::string name); 25 | virtual ~StringFile() override; 26 | 27 | virtual std::string getName() const override; 28 | virtual std::string getContent() override; 29 | virtual void saveCopyTo(const std::string &directoryPath) override; 30 | virtual void saveCopyTo(const std::string &directoryPath, 31 | const std::string &name) override; 32 | 33 | private: 34 | /// Content of the file. 35 | std::string content; 36 | 37 | /// Name of the file. 38 | std::string name; 39 | }; 40 | 41 | } // namespace internal 42 | } // namespace retdec 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /include/retdec/internal/resource_impl.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/resource_impl.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Base class of private implementation of resources. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_RESOURCE_IMPL_H 9 | #define RETDEC_INTERNAL_RESOURCE_IMPL_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "retdec/internal/connection.h" 17 | 18 | namespace retdec { 19 | namespace internal { 20 | 21 | class ResponseVerifyingConnection; 22 | 23 | /// 24 | /// Base class of private implementation of resources. 25 | /// 26 | class ResourceImpl { 27 | public: 28 | ResourceImpl( 29 | const std::string &id, 30 | const std::shared_ptr &conn, 31 | const std::string &serviceName, 32 | const std::string &resourcesName 33 | ); 34 | virtual ~ResourceImpl(); 35 | 36 | /// @name Status Update 37 | /// @{ 38 | bool shouldUpdateStatus(); 39 | void updateStatus(); 40 | void updateStatusIfNeeded(); 41 | 42 | virtual void updateResourceSpecificStatus(const Json::Value &jsonBody); 43 | /// @} 44 | 45 | /// Identifier. 46 | const std::string id; 47 | 48 | /// Connection to the API. 49 | const std::shared_ptr conn; 50 | 51 | /// Base URL of the resource. 52 | const Connection::Url baseUrl; 53 | 54 | /// URL to obtain the status of the resource. 55 | const Connection::Url statusUrl; 56 | 57 | /// Has the resource finished? 58 | bool finished = false; 59 | 60 | /// Has the resource succeeded? 61 | bool succeeded = false; 62 | 63 | /// Has the resource failed? 64 | bool failed = false; 65 | 66 | /// Error message. 67 | std::string error; 68 | }; 69 | 70 | } // namespace internal 71 | } // namespace retdec 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /include/retdec/internal/service_impl.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/service_impl.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Base class of private implementation of services. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_SERVICE_IMPL_H 9 | #define RETDEC_INTERNAL_SERVICE_IMPL_H 10 | 11 | #include 12 | #include 13 | 14 | #include "retdec/internal/utilities/connection.h" 15 | #include "retdec/settings.h" 16 | 17 | namespace retdec { 18 | 19 | class ResourceArguments; 20 | 21 | namespace internal { 22 | 23 | class ConnectionManager; 24 | 25 | /// 26 | /// Base class of private implementation of services. 27 | /// 28 | class ServiceImpl { 29 | public: 30 | ServiceImpl(const Settings &settings, 31 | const std::shared_ptr &connectionManager, 32 | const std::string &serviceName); 33 | virtual ~ServiceImpl() = 0; 34 | 35 | /// @name Request Arguments Creation 36 | /// @{ 37 | Connection::RequestArguments createRequestArguments( 38 | const ResourceArguments &args) const; 39 | Connection::RequestFiles createRequestFiles( 40 | const ResourceArguments &args) const; 41 | /// @} 42 | 43 | /// Settings. 44 | const Settings settings; 45 | 46 | /// Connection manager. 47 | const std::shared_ptr connectionManager; 48 | 49 | /// Base URL. 50 | const std::string baseUrl; 51 | }; 52 | 53 | } // namespace internal 54 | } // namespace retdec 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /include/retdec/internal/service_with_resources_impl.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/service_with_resources_impl.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Base class of private implementation of services with resources. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_SERVICE_WITH_RESOURCES_IMPL_H 9 | #define RETDEC_INTERNAL_SERVICE_WITH_RESOURCES_IMPL_H 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "retdec/internal/connection_manager.h" 17 | #include "retdec/internal/service_impl.h" 18 | 19 | namespace retdec { 20 | namespace internal { 21 | 22 | /// 23 | /// Base class of private implementation of services. 24 | /// 25 | class ServiceWithResourcesImpl: public ServiceImpl { 26 | public: 27 | ServiceWithResourcesImpl(const Settings &settings, 28 | const std::shared_ptr &connectionManager, 29 | const std::string &serviceName, 30 | const std::string &resourcesName); 31 | virtual ~ServiceWithResourcesImpl() override; 32 | 33 | /// 34 | /// Runs a new resource with the given arguments. 35 | /// 36 | template 37 | std::unique_ptr runResource(const ResourceArguments &args) { 38 | auto conn = connectionManager->newConnection(settings); 39 | auto response = conn->sendPostRequest( 40 | resourcesUrl, 41 | createRequestArguments(args), 42 | createRequestFiles(args) 43 | ); 44 | verifyRequestSucceeded(*response); 45 | auto jsonBody = response->bodyAsJson(); 46 | auto id = jsonBody.get("id", "?").asString(); 47 | return std::make_unique(id, conn); 48 | } 49 | 50 | /// URL to resources. 51 | const std::string resourcesUrl; 52 | }; 53 | 54 | } // namespace internal 55 | } // namespace retdec 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /include/retdec/internal/utilities/connection.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/connection.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Connection utilities. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_UTILITIES_CONNECTION_H 9 | #define RETDEC_INTERNAL_UTILITIES_CONNECTION_H 10 | 11 | #include 12 | 13 | #include "retdec/internal/connection.h" 14 | 15 | namespace retdec { 16 | namespace internal { 17 | 18 | bool requestSucceeded(const Connection::Response &response); 19 | void verifyRequestSucceeded(const Connection::Response &response); 20 | 21 | /// 22 | /// Connection wrapper verifying that requests succeed. 23 | /// 24 | /// This class wraps an existing connection. Then, when a response from a 25 | /// GET/POST request is received, it verifies that the request succeeded. If it 26 | /// failed, it throws ApiError or its subclass. 27 | /// 28 | class ResponseVerifyingConnection: public Connection { 29 | public: 30 | ResponseVerifyingConnection(const std::shared_ptr &conn); 31 | virtual ~ResponseVerifyingConnection(); 32 | 33 | virtual Url getApiUrl() const override; 34 | virtual std::unique_ptr sendGetRequest(const Url &url) override; 35 | virtual std::unique_ptr sendGetRequest(const Url &url, 36 | const RequestArguments &args) override; 37 | virtual std::unique_ptr sendPostRequest(const Url &url, 38 | const RequestArguments &args, const RequestFiles &files) override; 39 | 40 | private: 41 | /// Wrapped connection. 42 | std::shared_ptr conn; 43 | }; 44 | 45 | } // namespace internal 46 | } // namespace retdec 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/retdec/internal/utilities/container.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/container.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Utilities for containers. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_UTILITIES_CONTAINER_H 9 | #define RETDEC_INTERNAL_UTILITIES_CONTAINER_H 10 | 11 | namespace retdec { 12 | namespace internal { 13 | 14 | /// @name Map 15 | /// @{ 16 | 17 | /// 18 | /// Has @a map the given key? 19 | /// 20 | template 21 | inline bool hasKey(const Map &map, const Key &key) { 22 | return map.find(key) != map.end(); 23 | } 24 | 25 | /// 26 | /// Returns the value of the given key in @a map or the default value. 27 | /// 28 | template 29 | inline typename Map::mapped_type getValue(const Map &map, 30 | const Key &key) { 31 | auto it = map.find(key); 32 | return it != map.end() ? it->second : typename Map::mapped_type(); 33 | } 34 | 35 | /// @} 36 | 37 | } // namespace internal 38 | } // namespace retdec 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /include/retdec/internal/utilities/json.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/json.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Utilities for working with the JSON format. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_UTILITIES_JSON_H 9 | #define RETDEC_INTERNAL_UTILITIES_JSON_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "retdec/exceptions.h" 16 | 17 | namespace retdec { 18 | namespace internal { 19 | 20 | /// @name JSON 21 | /// @{ 22 | 23 | /// 24 | /// Exception thrown when JSON decoding fails. 25 | /// 26 | class JsonDecodingError: public Error { 27 | public: 28 | JsonDecodingError(const std::string &formattedErrors); 29 | }; 30 | 31 | Json::Value toJson(const std::string &str); 32 | 33 | /// @} 34 | 35 | } // namespace internal 36 | } // namespace retdec 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /include/retdec/internal/utilities/os.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/os.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Operating-system-related utilities. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_UTILITIES_OS_H 9 | #define RETDEC_INTERNAL_UTILITIES_OS_H 10 | 11 | #include 12 | 13 | // Obtain the used operating system. 14 | // http://sourceforge.net/p/predef/wiki/OperatingSystems/ 15 | #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(__WINDOWS__) || defined(__CYGWIN__) 16 | #define RETDEC_OS_WINDOWS 17 | #elif defined(__ANDROID__) 18 | #define RETDEC_OS_ANDROID 19 | #elif defined(__linux__) 20 | #define RETDEC_OS_LINUX 21 | #elif defined(__APPLE__) || defined(__MACH__) 22 | #define RETDEC_OS_MACOS 23 | #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 24 | #define RETDEC_OS_BSD 25 | #elif defined(__unix__) || defined(__unix) 26 | #define RETDEC_OS_UNIX 27 | #endif 28 | 29 | namespace retdec { 30 | namespace internal { 31 | 32 | /// @name Operating System 33 | /// @{ 34 | 35 | std::string operatingSystemName(); 36 | std::string fileNameFromPath(const std::string &path); 37 | std::string readFile(const std::string &path); 38 | void writeFile(const std::string &path, const std::string &content); 39 | void copyFile(const std::string &srcPath, const std::string &dstPath); 40 | std::string joinPaths(const std::string &path1, const std::string &path2); 41 | 42 | /// 43 | /// Joins the given paths. 44 | /// 45 | template 46 | inline std::string joinPaths(const std::string &path1, const std::string &path2, 47 | const Paths &... paths) { 48 | return joinPaths(path1, path2) + joinPaths(paths...); 49 | } 50 | 51 | void sleep(int milliseconds); 52 | 53 | /// @} 54 | 55 | } // namespace internal 56 | } // namespace retdec 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /include/retdec/internal/utilities/smart_ptr.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/smart_ptr.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Utilities for smart pointers. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_UTILITIES_SMART_PTR_H 9 | #define RETDEC_INTERNAL_UTILITIES_SMART_PTR_H 10 | 11 | #include 12 | 13 | namespace retdec { 14 | namespace internal { 15 | 16 | /// @name Smart Pointers 17 | /// @{ 18 | 19 | /// 20 | /// Casts the given shared pointer to a pointer of a different type. 21 | /// 22 | /// @param[in] ptr Pointer to be casted. 23 | /// 24 | /// @tparam To Output type. 25 | /// @tparam From Input type. 26 | /// 27 | /// It represents a more concise alternative to 28 | /// std::dynamic_pointer_cast(ptr). 29 | /// 30 | template 31 | std::shared_ptr cast(const std::shared_ptr &ptr) noexcept { 32 | return std::dynamic_pointer_cast(ptr); 33 | } 34 | 35 | /// 36 | /// Checks if @a ptr is of type @c To or can be casted from @c From to @c To. 37 | /// 38 | /// @param[in] ptr Pointer to be tested. 39 | /// 40 | /// @tparam To Output type. 41 | /// @tparam From Input type. 42 | /// 43 | /// It represents a more concise and readable alternative to 44 | /// std::dynamic_pointer_cast(ptr) != nullptr. 45 | /// 46 | template 47 | bool isa(const std::shared_ptr &ptr) noexcept { 48 | return cast(ptr) != nullptr; 49 | } 50 | 51 | /// @} 52 | 53 | } // namespace internal 54 | } // namespace retdec 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /include/retdec/internal/utilities/string.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/string.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Utilities for strings. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_UTILITIES_STRING_H 9 | #define RETDEC_INTERNAL_UTILITIES_STRING_H 10 | 11 | #include 12 | 13 | namespace retdec { 14 | namespace internal { 15 | 16 | /// @name String 17 | /// @{ 18 | 19 | std::string capitalizeWords(std::string s); 20 | 21 | /// @} 22 | 23 | } // namespace internal 24 | } // namespace retdec 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/retdec/resource.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file resource.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Base class of all resources. 6 | /// 7 | 8 | #ifndef RETDEC_RESOURCE_H 9 | #define RETDEC_RESOURCE_H 10 | 11 | #include 12 | 13 | namespace retdec { 14 | 15 | namespace internal { 16 | 17 | class ResourceImpl; 18 | 19 | } // namespace internal 20 | 21 | /// 22 | /// Base class of all resources. 23 | /// 24 | class Resource { 25 | public: 26 | /// @cond internal 27 | Resource(std::unique_ptr impl); 28 | /// @endcond 29 | virtual ~Resource() = 0; 30 | 31 | /// @name Querying 32 | /// @{ 33 | std::string getId() const; 34 | bool hasFinished(); 35 | bool hasFinished() const noexcept; 36 | bool hasSucceeded(); 37 | bool hasSucceeded() const noexcept; 38 | bool hasFailed(); 39 | bool hasFailed() const noexcept; 40 | std::string getError(); 41 | std::string getError() const; 42 | /// @} 43 | 44 | /// @name Disabled 45 | /// @{ 46 | Resource(const Resource &) = delete; 47 | Resource(Resource &&) = delete; 48 | Resource &operator=(const Resource &) = delete; 49 | Resource &operator=(Resource &&) = delete; 50 | /// @} 51 | 52 | protected: 53 | /// Private implementation. 54 | std::unique_ptr pimpl; 55 | }; 56 | 57 | } // namespace retdec 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /include/retdec/resource_arguments.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/resource_arguments.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Base class of arguments for all services. 6 | /// 7 | 8 | #ifndef RETDEC_RESOURCE_ARGUMENTS_H 9 | #define RETDEC_RESOURCE_ARGUMENTS_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace retdec { 16 | 17 | class File; 18 | 19 | /// 20 | /// Base class of arguments for all services. 21 | /// 22 | class ResourceArguments { 23 | private: 24 | /// Container to store arguments. 25 | using Arguments = std::map; 26 | 27 | /// Container to store files. 28 | using Files = std::map>; 29 | 30 | public: 31 | /// Iterator for arguments. 32 | using ArgumentIterator = Arguments::const_iterator; 33 | 34 | /// Iterator for files. 35 | using FileIterator = Files::const_iterator; 36 | 37 | public: 38 | /// @name Construction, Assignment, and Destruction 39 | /// @{ 40 | ResourceArguments(); 41 | ResourceArguments(const ResourceArguments &other); 42 | ResourceArguments(ResourceArguments &&other); 43 | ResourceArguments &operator=(const ResourceArguments &other); 44 | ResourceArguments &operator=(ResourceArguments &&other); 45 | ~ResourceArguments(); 46 | /// @} 47 | 48 | /// @name Generic Access To Arguments 49 | /// @{ 50 | ResourceArguments &argument(const std::string &id, 51 | const std::string &value); 52 | ResourceArguments withArgument(const std::string &id, 53 | const std::string &value) const; 54 | bool hasArgument(const std::string &id) const; 55 | std::string argument(const std::string &id) const; 56 | ArgumentIterator argumentsBegin() const; 57 | ArgumentIterator argumentsEnd() const; 58 | /// @} 59 | 60 | /// @name Generic Access To Files 61 | /// @{ 62 | ResourceArguments &file(const std::string &id, 63 | const std::shared_ptr &file); 64 | ResourceArguments withFile(const std::string &id, 65 | const std::shared_ptr &file) const; 66 | bool hasFile(const std::string &id) const; 67 | std::shared_ptr file(const std::string &id) const; 68 | FileIterator filesBegin() const; 69 | FileIterator filesEnd() const; 70 | /// @} 71 | 72 | protected: 73 | /// Arguments. 74 | Arguments arguments; 75 | 76 | /// Files. 77 | Files files; 78 | }; 79 | 80 | } // namespace retdec 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /include/retdec/retdec.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Header file for the library. 6 | /// 7 | /// This header file includes all the header files provided by the library for 8 | /// clients to use. 9 | /// 10 | 11 | #ifndef RETDEC_RETDEC_H 12 | #define RETDEC_RETDEC_H 13 | 14 | #include "retdec/analysis.h" 15 | #include "retdec/analysis_arguments.h" 16 | #include "retdec/decompilation.h" 17 | #include "retdec/decompilation_arguments.h" 18 | #include "retdec/decompiler.h" 19 | #include "retdec/exceptions.h" 20 | #include "retdec/file.h" 21 | #include "retdec/fileinfo.h" 22 | #include "retdec/settings.h" 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/retdec/service.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/service.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Base class of all services. 6 | /// 7 | 8 | #ifndef RETDEC_SERVICE_H 9 | #define RETDEC_SERVICE_H 10 | 11 | #include 12 | 13 | namespace retdec { 14 | 15 | namespace internal { 16 | 17 | class ServiceImpl; 18 | 19 | } // namespace internal 20 | 21 | /// 22 | /// Base class of all services. 23 | /// 24 | class Service { 25 | public: 26 | /// @cond internal 27 | Service(std::unique_ptr impl); 28 | /// @endcond 29 | virtual ~Service() = 0; 30 | 31 | /// @name Disabled 32 | /// @{ 33 | Service(const Service &) = delete; 34 | Service(Service &&) = delete; 35 | Service &operator=(const Service &) = delete; 36 | Service &operator=(Service &&) = delete; 37 | /// @} 38 | 39 | protected: 40 | /// Private implementation. 41 | std::unique_ptr pimpl; 42 | }; 43 | 44 | } // namespace retdec 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/retdec/settings.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/settings.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Library settings. 6 | /// 7 | 8 | #ifndef RETDEC_SETTINGS_H 9 | #define RETDEC_SETTINGS_H 10 | 11 | #include 12 | #include 13 | 14 | namespace retdec { 15 | 16 | /// 17 | /// Library settings. 18 | /// 19 | class Settings { 20 | public: 21 | /// @name Construction, Assignment, and Destruction 22 | /// @{ 23 | Settings(); 24 | Settings(const Settings &other); 25 | Settings(Settings &&other); 26 | Settings &operator=(const Settings &other); 27 | Settings &operator=(Settings &&other); 28 | ~Settings(); 29 | /// @} 30 | 31 | /// @name API Key 32 | /// @{ 33 | Settings &apiKey(const std::string &apiKey); 34 | Settings withApiKey(const std::string &apiKey) const; 35 | std::string apiKey() const; 36 | /// @} 37 | 38 | /// @name API URL 39 | /// @{ 40 | Settings &apiUrl(const std::string &apiUrl); 41 | Settings withApiUrl(const std::string &apiUrl) const; 42 | std::string apiUrl() const; 43 | /// @} 44 | 45 | /// @name User Agent 46 | /// @{ 47 | Settings &userAgent(const std::string &userAgent); 48 | Settings withUserAgent(const std::string &userAgent) const; 49 | std::string userAgent() const; 50 | /// @} 51 | 52 | public: 53 | /// @name Default Values 54 | /// @{ 55 | static const std::string DefaultApiUrl; 56 | static const std::string DefaultApiKey; 57 | static const std::string DefaultUserAgent; 58 | /// @} 59 | 60 | private: 61 | /// URL to the API. 62 | std::string apiUrl_; 63 | 64 | /// API key. 65 | std::string apiKey_; 66 | 67 | /// User agent. 68 | std::string userAgent_; 69 | }; 70 | 71 | } // namespace retdec 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /include/retdec/test.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/test.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Testing service. 6 | /// 7 | 8 | #ifndef RETDEC_TEST_H 9 | #define RETDEC_TEST_H 10 | 11 | #include 12 | 13 | #include "retdec/service.h" 14 | 15 | namespace retdec { 16 | 17 | class Settings; 18 | 19 | namespace internal { 20 | 21 | class ConnectionManager; 22 | class TestImpl; 23 | 24 | } // namespace internal 25 | 26 | /// 27 | /// Runner of analyses. 28 | /// 29 | class Test: public Service { 30 | public: 31 | /// @name Construction and Destruction 32 | /// @{ 33 | Test(const Settings &settings); 34 | /// @cond internal 35 | Test(const Settings &settings, 36 | const std::shared_ptr<::retdec::internal::ConnectionManager> &connectionManager); 37 | /// @endcond 38 | virtual ~Test() override; 39 | /// @} 40 | 41 | /// @name Testing 42 | /// @{ 43 | void auth(); 44 | /// @} 45 | 46 | private: 47 | internal::TestImpl *impl() noexcept; 48 | const internal::TestImpl *impl() const noexcept; 49 | }; 50 | 51 | } // namespace retdec 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## 2 | ## Project: retdec-cpp 3 | ## Copyright: (c) 2015 by Petr Zemek and contributors 4 | ## License: MIT, see the LICENSE file for more details 5 | ## 6 | ## CMake configuration file for the source files. 7 | ## 8 | 9 | add_subdirectory(tools) 10 | add_subdirectory(retdec) 11 | -------------------------------------------------------------------------------- /src/retdec/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## 2 | ## Project: retdec-cpp 3 | ## Copyright: (c) 2015 by Petr Zemek and contributors 4 | ## License: MIT, see the LICENSE file for more details 5 | ## 6 | ## CMake configuration file for the library source files. 7 | ## 8 | 9 | set(RETDEC_SOURCES 10 | analysis.cpp 11 | analysis_arguments.cpp 12 | decompilation.cpp 13 | decompilation_arguments.cpp 14 | decompiler.cpp 15 | exceptions.cpp 16 | file.cpp 17 | fileinfo.cpp 18 | internal/connection.cpp 19 | internal/connection_manager.cpp 20 | internal/connection_managers/real_connection_manager.cpp 21 | internal/connections/real_connection.cpp 22 | internal/files/filesystem_file.cpp 23 | internal/files/string_file.cpp 24 | internal/resource_impl.cpp 25 | internal/service_impl.cpp 26 | internal/service_with_resources_impl.cpp 27 | internal/utilities/connection.cpp 28 | internal/utilities/json.cpp 29 | internal/utilities/os.cpp 30 | internal/utilities/string.cpp 31 | resource.cpp 32 | resource_arguments.cpp 33 | service.cpp 34 | settings.cpp 35 | test.cpp 36 | ) 37 | 38 | add_library(retdec ${RETDEC_SOURCES}) 39 | if(NOT CPPNETLIB_FOUND) 40 | add_dependencies(retdec cpp-netlib) 41 | endif() 42 | if(NOT JsonCpp_FOUND) 43 | add_dependencies(retdec json-cpp) 44 | endif() 45 | target_link_libraries(retdec 46 | ${Boost_LIBRARIES} 47 | ${OPENSSL_LIBRARIES} 48 | ${CPPNETLIB_LIBRARIES} 49 | ${JsonCpp_LIBRARY} 50 | ${CMAKE_THREAD_LIBS_INIT} 51 | ) 52 | 53 | install(TARGETS retdec DESTINATION "${INSTALL_LIB_DIR}" EXPORT retdec) 54 | install(EXPORT retdec DESTINATION "${INSTALL_LIB_CMAKE_DIR}") 55 | 56 | # Configuration file for find_package(retdec). 57 | configure_file( 58 | retdec-config.cmake.in 59 | "${CMAKE_BINARY_DIR}/retdec-config-install.cmake" 60 | @ONLY 61 | ) 62 | install( 63 | FILES "${CMAKE_BINARY_DIR}/retdec-config-install.cmake" 64 | DESTINATION "${INSTALL_LIB_CMAKE_DIR}" 65 | RENAME retdec-config.cmake 66 | ) 67 | -------------------------------------------------------------------------------- /src/retdec/analysis.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/analysis.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the analysis. 6 | /// 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include "retdec/analysis.h" 13 | #include "retdec/exceptions.h" 14 | #include "retdec/file.h" 15 | #include "retdec/internal/connections/real_connection.h" 16 | #include "retdec/internal/resource_impl.h" 17 | #include "retdec/internal/utilities/connection.h" 18 | #include "retdec/internal/utilities/os.h" 19 | 20 | using namespace retdec::internal; 21 | 22 | namespace retdec { 23 | namespace internal { 24 | 25 | /// 26 | /// Private implementation of Analysis. 27 | /// 28 | class AnalysisImpl: public ResourceImpl { 29 | public: 30 | AnalysisImpl( 31 | const std::string &id, 32 | const std::shared_ptr &conn, 33 | const std::string &serviceName, 34 | const std::string &resourcesName 35 | ); 36 | virtual ~AnalysisImpl() override; 37 | 38 | void getAndStoreOutputAsFile(); 39 | 40 | /// URL to obtain the output of the analysis. 41 | const Connection::Url outputUrl; 42 | 43 | /// Output as a file. 44 | std::shared_ptr outputAsFile; 45 | }; 46 | 47 | /// 48 | /// Constructs a private implementation. 49 | /// 50 | /// @param[in] id Identifier of the resource. 51 | /// @param[in] conn Connection to be used to communicate with the API. 52 | /// @param[in] serviceName Name of the service. 53 | /// @param[in] resourcesName Name of the resources (plural). 54 | /// 55 | AnalysisImpl::AnalysisImpl( 56 | const std::string &id, 57 | const std::shared_ptr &conn, 58 | const std::string &serviceName, 59 | const std::string &resourcesName 60 | ): ResourceImpl(id, conn, serviceName, resourcesName), 61 | outputUrl(baseUrl + "/output") 62 | {} 63 | 64 | // Override. 65 | AnalysisImpl::~AnalysisImpl() = default; 66 | 67 | /// 68 | /// Gets and stores the results as an output file. 69 | /// 70 | void AnalysisImpl::getAndStoreOutputAsFile() { 71 | auto response = conn->sendGetRequest(outputUrl); 72 | outputAsFile = response->bodyAsFile(); 73 | } 74 | 75 | } // namespace internal 76 | 77 | /// 78 | /// Constructs an analysis. 79 | /// 80 | Analysis::Analysis(const std::string &id,const std::shared_ptr &conn): 81 | Resource(std::make_unique( 82 | id, 83 | conn, 84 | "fileinfo", 85 | "analyses" 86 | )) {} 87 | 88 | // Override. 89 | Analysis::~Analysis() = default; 90 | 91 | /// 92 | /// Waits until the analysis is finished. 93 | /// 94 | /// @param[in] onError Should AnalysisError be thrown when the 95 | /// analysis fails? 96 | /// 97 | /// May access the API. 98 | /// 99 | void Analysis::waitUntilFinished(OnError onError) { 100 | // Currently, there is no other choice but polling. 101 | while (!impl()->finished) { 102 | impl()->updateStatus(); 103 | 104 | // Wait a bit before the next try to update the status. 105 | sleep(500); 106 | } 107 | 108 | if (impl()->failed && onError == OnError::Throw) { 109 | throw AnalysisError(impl()->error); 110 | } 111 | } 112 | 113 | /// 114 | /// Returns the results of the analysis as a file. 115 | /// 116 | /// This function should be called only after the analysis has finished, 117 | /// i.e. hasFinished() returns @c true. 118 | /// 119 | /// May access the API. 120 | /// 121 | std::shared_ptr Analysis::getOutputAsFile() { 122 | if (!impl()->outputAsFile) { 123 | impl()->getAndStoreOutputAsFile(); 124 | } 125 | return impl()->outputAsFile; 126 | } 127 | 128 | /// 129 | /// Returns the results of the analysis. 130 | /// 131 | /// This function should be called only after the analysis has finished, 132 | /// i.e. hasFinished() returns @c true. 133 | /// 134 | /// May access the API. 135 | /// 136 | std::string Analysis::getOutput() { 137 | return getOutputAsFile()->getContent(); 138 | } 139 | 140 | /// 141 | /// Returns a properly cast private implementation. 142 | /// 143 | AnalysisImpl *Analysis::impl() noexcept { 144 | return static_cast(pimpl.get()); 145 | } 146 | 147 | /// 148 | /// Constant overload of impl(). 149 | /// 150 | const AnalysisImpl *Analysis::impl() const noexcept { 151 | return static_cast(pimpl.get()); 152 | } 153 | 154 | } // namespace retdec 155 | -------------------------------------------------------------------------------- /src/retdec/analysis_arguments.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/analysis_arguments.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the analysis arguments. 6 | /// 7 | 8 | #include "retdec/analysis_arguments.h" 9 | #include "retdec/internal/utilities/container.h" 10 | 11 | using namespace retdec::internal; 12 | 13 | namespace retdec { 14 | 15 | namespace { 16 | 17 | /// ID for the verbose argument. 18 | const std::string VerboseId = "verbose"; 19 | 20 | /// ID for the input file. 21 | const std::string InputFileId = "input"; 22 | 23 | } // anonymous namespace 24 | 25 | /// 26 | /// Constructs default arguments. 27 | /// 28 | AnalysisArguments::AnalysisArguments() = default; 29 | 30 | /// 31 | /// Copy-constructs arguments from the given arguments. 32 | /// 33 | AnalysisArguments::AnalysisArguments( 34 | const AnalysisArguments &) = default; 35 | 36 | /// 37 | /// Move-constructs arguments from the given arguments. 38 | /// 39 | AnalysisArguments::AnalysisArguments( 40 | AnalysisArguments &&) = default; 41 | 42 | /// 43 | /// Copy-assigns the given arguments. 44 | /// 45 | AnalysisArguments &AnalysisArguments::operator=( 46 | const AnalysisArguments &) = default; 47 | 48 | /// 49 | /// Move-assigns the given arguments. 50 | /// 51 | AnalysisArguments &AnalysisArguments::operator=( 52 | AnalysisArguments &&) = default; 53 | 54 | /// 55 | /// Destructs the arguments. 56 | /// 57 | AnalysisArguments::~AnalysisArguments() = default; 58 | 59 | /// 60 | /// Sets the verbose mode. 61 | /// 62 | /// When @a verbose is @c "yes", the analysis produces all the supported 63 | /// information about the input file. Otherwise, when @a verbose is @c "no" 64 | /// (the default), the analysis produces only basic information. 65 | /// 66 | AnalysisArguments &AnalysisArguments::verbose(const std::string &verbose) { 67 | return argument(VerboseId, verbose); 68 | } 69 | 70 | /// 71 | /// Returns a copy of the arguments with a verbose mode. 72 | /// 73 | /// See the description of verbose(const std::string &verbose) for more details. 74 | /// 75 | AnalysisArguments AnalysisArguments::withVerbose(const std::string &verbose) const { 76 | return withArgument(VerboseId, verbose); 77 | } 78 | 79 | /// 80 | /// Is the verbose argument set? 81 | /// 82 | /// It returns @c true even when @c verbose was explicitly set to @c "no". It 83 | /// only returns @c false when the verbose argument was not set. 84 | /// 85 | bool AnalysisArguments::hasVerbose() const { 86 | return hasArgument(VerboseId); 87 | } 88 | 89 | /// 90 | /// Should the analysis be run in the verbose mode? 91 | /// 92 | std::string AnalysisArguments::verbose() const { 93 | return getValue(arguments, VerboseId); 94 | } 95 | 96 | /// 97 | /// Sets the input file. 98 | /// 99 | AnalysisArguments &AnalysisArguments::inputFile( 100 | const std::shared_ptr &file) { 101 | return this->file(InputFileId, file); 102 | } 103 | 104 | /// 105 | /// Returns a copy of the arguments with a different input file. 106 | /// 107 | AnalysisArguments AnalysisArguments::withInputFile( 108 | const std::shared_ptr &file) const { 109 | return withFile(InputFileId, file); 110 | } 111 | 112 | /// 113 | /// Is the input file set? 114 | /// 115 | bool AnalysisArguments::hasInputFile() const { 116 | return hasFile(InputFileId); 117 | } 118 | 119 | /// 120 | /// Returns the input file. 121 | /// 122 | std::shared_ptr AnalysisArguments::inputFile() const { 123 | return file(InputFileId); 124 | } 125 | 126 | /// 127 | /// Sets the argument of the given ID to the given value. 128 | /// 129 | AnalysisArguments &AnalysisArguments::argument( 130 | const std::string &id, const std::string &value) { 131 | return static_cast( 132 | ResourceArguments::argument(id, value) 133 | ); 134 | } 135 | 136 | /// 137 | /// Returns a copy of the arguments with a differing argument of the given ID. 138 | /// 139 | AnalysisArguments AnalysisArguments::withArgument( 140 | const std::string &id, const std::string &value) const { 141 | auto copy = *this; 142 | copy.argument(id, value); 143 | return copy; 144 | } 145 | 146 | /// 147 | /// Sets the file of the given ID to the given value. 148 | /// 149 | AnalysisArguments &AnalysisArguments::file( 150 | const std::string &id, const std::shared_ptr &file) { 151 | return static_cast( 152 | ResourceArguments::file(id, file) 153 | ); 154 | } 155 | 156 | /// 157 | /// Returns a copy of the files with a differing file of the given ID. 158 | /// 159 | AnalysisArguments AnalysisArguments::withFile( 160 | const std::string &id, const std::shared_ptr &file) const { 161 | auto copy = *this; 162 | copy.file(id, file); 163 | return copy; 164 | } 165 | 166 | } // namespace retdec 167 | -------------------------------------------------------------------------------- /src/retdec/decompilation.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/decompilation.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the decompilation. 6 | /// 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include "retdec/decompilation.h" 13 | #include "retdec/exceptions.h" 14 | #include "retdec/file.h" 15 | #include "retdec/internal/connections/real_connection.h" 16 | #include "retdec/internal/resource_impl.h" 17 | #include "retdec/internal/utilities/connection.h" 18 | #include "retdec/internal/utilities/os.h" 19 | 20 | using namespace retdec::internal; 21 | 22 | namespace retdec { 23 | 24 | namespace { 25 | 26 | /// Callback doing nothing. 27 | const Decompilation::Callback CallbackDoingNothing = [](const Decompilation &) {}; 28 | 29 | } // anonymous namespace 30 | 31 | namespace internal { 32 | 33 | /// 34 | /// Private implementation of Decompilation. 35 | /// 36 | class DecompilationImpl: public ResourceImpl { 37 | public: 38 | DecompilationImpl( 39 | const std::string &id, 40 | const std::shared_ptr &conn, 41 | const std::string &serviceName, 42 | const std::string &resourcesName 43 | ); 44 | virtual ~DecompilationImpl() override; 45 | 46 | /// @name Status Update 47 | /// @{ 48 | virtual void updateResourceSpecificStatus(const Json::Value &jsonBody) override; 49 | /// @} 50 | 51 | void getAndStoreOutputHllFile(); 52 | 53 | /// URL to obtain the outputs of the resource. 54 | const Connection::Url outputsUrl; 55 | 56 | /// Completion (in percentages, 0-100). 57 | int completion = 0; 58 | 59 | /// Output HLL file. 60 | std::shared_ptr outputHllFile; 61 | }; 62 | 63 | /// 64 | /// Constructs a private implementation. 65 | /// 66 | /// @param[in] id Identifier of the resource. 67 | /// @param[in] conn Connection to be used to communicate with the API. 68 | /// @param[in] serviceName Name of the service. 69 | /// @param[in] resourcesName Name of the resources (plural). 70 | /// 71 | DecompilationImpl::DecompilationImpl( 72 | const std::string &id, 73 | const std::shared_ptr &conn, 74 | const std::string &serviceName, 75 | const std::string &resourcesName 76 | ): ResourceImpl(id, conn, serviceName, resourcesName), 77 | outputsUrl(baseUrl + "/outputs") 78 | {} 79 | 80 | // Override. 81 | DecompilationImpl::~DecompilationImpl() = default; 82 | 83 | // Override. 84 | void DecompilationImpl::updateResourceSpecificStatus(const Json::Value &jsonBody) { 85 | completion = jsonBody.get("completion", false).asInt(); 86 | } 87 | 88 | /// 89 | /// Gets and stores the output HLL file. 90 | /// 91 | void DecompilationImpl::getAndStoreOutputHllFile() { 92 | auto response = conn->sendGetRequest(outputsUrl + "/hll"); 93 | outputHllFile = response->bodyAsFile(); 94 | } 95 | 96 | } // namespace internal 97 | 98 | /// 99 | /// Constructs a decompilation. 100 | /// 101 | Decompilation::Decompilation(const std::string &id, 102 | const std::shared_ptr &conn): 103 | Resource(std::make_unique( 104 | id, 105 | conn, 106 | "decompiler", 107 | "decompilations" 108 | )) {} 109 | 110 | // Override. 111 | Decompilation::~Decompilation() = default; 112 | 113 | /// 114 | /// Returns the completion status (in percentages, 0-100). 115 | /// 116 | /// May access the API. 117 | /// 118 | int Decompilation::getCompletion() { 119 | impl()->updateStatusIfNeeded(); 120 | return impl()->completion; 121 | } 122 | 123 | /// 124 | /// Returns the completion status (in percentages, 0-100). 125 | /// 126 | /// Does not access the API. 127 | /// 128 | int Decompilation::getCompletion() const noexcept { 129 | return impl()->completion; 130 | } 131 | 132 | /// 133 | /// Waits until the decompilation is finished. 134 | /// 135 | /// @param[in] onError Should DecompilationError be thrown when the 136 | /// decompilation fails? 137 | /// 138 | /// May access the API. 139 | /// 140 | void Decompilation::waitUntilFinished(OnError onError) { 141 | waitUntilFinished(CallbackDoingNothing, onError); 142 | } 143 | 144 | /// 145 | /// Waits and reports changes until the decompilation is finished. 146 | /// 147 | /// @param[in] callback Function to be called when the decompilation status 148 | /// changes. 149 | /// @param[in] onError Should DecompilationError be thrown when the 150 | /// decompilation fails? 151 | /// 152 | /// May access the API. 153 | /// 154 | void Decompilation::waitUntilFinished(const Callback &callback, 155 | OnError onError) { 156 | // Currently, there is no other choice but polling. 157 | while (!impl()->finished) { 158 | auto lastCompletion = impl()->completion; 159 | impl()->updateStatus(); 160 | if (impl()->completion != lastCompletion) { 161 | callback(*this); 162 | } 163 | // Wait a bit before the next try to update the status. 164 | sleep(500); 165 | } 166 | 167 | if (impl()->failed && onError == OnError::Throw) { 168 | throw DecompilationError(impl()->error); 169 | } 170 | } 171 | 172 | /// 173 | /// Returns the output HLL file (C, Python'). 174 | /// 175 | /// This function should be called only after the decompilation has finished, 176 | /// i.e. hasFinished() returns @c true. 177 | /// 178 | /// May access the API. 179 | /// 180 | std::shared_ptr Decompilation::getOutputHllFile() { 181 | if (!impl()->outputHllFile) { 182 | impl()->getAndStoreOutputHllFile(); 183 | } 184 | return impl()->outputHllFile; 185 | } 186 | 187 | /// 188 | /// Returns the content of the output HLL file (C, Python'). 189 | /// 190 | /// This function should be called only after the decompilation has finished, 191 | /// i.e. hasFinished() returns @c true. 192 | /// 193 | /// May access the API. 194 | /// 195 | std::string Decompilation::getOutputHll() { 196 | return getOutputHllFile()->getContent(); 197 | } 198 | 199 | /// 200 | /// Returns a properly cast private implementation. 201 | /// 202 | DecompilationImpl *Decompilation::impl() noexcept { 203 | return static_cast(pimpl.get()); 204 | } 205 | 206 | /// 207 | /// Constant overload of impl(). 208 | /// 209 | const DecompilationImpl *Decompilation::impl() const noexcept { 210 | return static_cast(pimpl.get()); 211 | } 212 | 213 | } // namespace retdec 214 | -------------------------------------------------------------------------------- /src/retdec/decompilation_arguments.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/decompilation_arguments.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the decompilation arguments. 6 | /// 7 | 8 | #include "retdec/decompilation_arguments.h" 9 | #include "retdec/internal/utilities/container.h" 10 | 11 | using namespace retdec::internal; 12 | 13 | namespace retdec { 14 | 15 | namespace { 16 | 17 | /// ID for the input file. 18 | const std::string InputFileId = "input"; 19 | 20 | /// ID for the mode argument. 21 | const std::string ModeId = "mode"; 22 | 23 | /// ID for the ranges argument of selective decompilation. 24 | const std::string SelDecompRangesId = "sel_decomp_ranges"; 25 | 26 | /// ID for the decoding argument of selective decompilation. 27 | const std::string SelDecompDecodingId = "sel_decomp_decoding"; 28 | 29 | } // anonymous namespace 30 | 31 | /// 32 | /// Constructs default arguments. 33 | /// 34 | DecompilationArguments::DecompilationArguments() = default; 35 | 36 | /// 37 | /// Copy-constructs arguments from the given arguments. 38 | /// 39 | DecompilationArguments::DecompilationArguments( 40 | const DecompilationArguments &) = default; 41 | 42 | /// 43 | /// Move-constructs arguments from the given arguments. 44 | /// 45 | DecompilationArguments::DecompilationArguments( 46 | DecompilationArguments &&) = default; 47 | 48 | /// 49 | /// Copy-assigns the given arguments. 50 | /// 51 | DecompilationArguments &DecompilationArguments::operator=( 52 | const DecompilationArguments &) = default; 53 | 54 | /// 55 | /// Move-assigns the given arguments. 56 | /// 57 | DecompilationArguments &DecompilationArguments::operator=( 58 | DecompilationArguments &&) = default; 59 | 60 | /// 61 | /// Destructs the arguments. 62 | /// 63 | DecompilationArguments::~DecompilationArguments() = default; 64 | 65 | /// 66 | /// Sets the mode. 67 | /// 68 | /// Available modes are: 69 | /// - bin: %Decompilation of a binary file in the ELF or WinPE format. 70 | /// - c: %Decompilation of a C file. 71 | /// 72 | DecompilationArguments &DecompilationArguments::mode(const std::string &mode) { 73 | return argument(ModeId, mode); 74 | } 75 | 76 | /// 77 | /// Returns a copy of the arguments with a different mode. 78 | /// 79 | /// See the description of mode(const std::string &mode) for more 80 | /// details. 81 | /// 82 | DecompilationArguments DecompilationArguments::withMode( 83 | const std::string &mode) const { 84 | return withArgument(ModeId, mode); 85 | } 86 | 87 | /// 88 | /// Is the mode set? 89 | /// 90 | bool DecompilationArguments::hasMode() const { 91 | return hasArgument(ModeId); 92 | } 93 | 94 | /// 95 | /// Returns the mode. 96 | /// 97 | std::string DecompilationArguments::mode() const { 98 | return argument(ModeId); 99 | } 100 | 101 | /// 102 | /// Sets ranges for selective decompilation. 103 | /// 104 | /// Each range is of the form ADDRESS-ADDRESS, where ADDRESS 105 | /// is a non-negative hexadecimal number. The ranges have to be divided by 106 | /// commas. The addresses are case-insensitive, so 0xFF is the same as 107 | /// 0xff. The addresses can be surrounded by spaces. 108 | /// 109 | /// @par Examples 110 | /// @code 111 | /// args.selDecompRanges("0x0-0xffff") 112 | /// args.selDecompRanges("0x0-0x2eef,0x3000-0x4fff") 113 | /// args.selDecompRanges(" 0x0 - 0xfa, 0xFC - 0xFF ") 114 | /// @endcode 115 | /// 116 | DecompilationArguments &DecompilationArguments::selDecompRanges( 117 | const std::string &ranges) { 118 | return argument(SelDecompRangesId, ranges); 119 | } 120 | 121 | /// 122 | /// Returns a copy of the arguments with a different ranges for selective 123 | /// decompilation. 124 | /// 125 | /// See the description of selDecompRanges(const std::string &ranges) 126 | /// for more details. 127 | /// 128 | DecompilationArguments DecompilationArguments::withSelDecompRanges( 129 | const std::string &ranges) { 130 | return withArgument(SelDecompRangesId, ranges); 131 | } 132 | 133 | /// 134 | /// Are the ranges for selective decompilation set? 135 | /// 136 | bool DecompilationArguments::hasSelDecompRanges() const { 137 | return hasArgument(SelDecompRangesId); 138 | } 139 | 140 | /// 141 | /// Returns the ranges for selective decompilation. 142 | /// 143 | std::string DecompilationArguments::selDecompRanges() const { 144 | return argument(SelDecompRangesId); 145 | } 146 | 147 | /// 148 | /// Sets type of decoding for selective decompilation. 149 | /// 150 | DecompilationArguments &DecompilationArguments::selDecompDecoding( 151 | const std::string &decoding) { 152 | return argument(SelDecompDecodingId, decoding); 153 | } 154 | 155 | /// 156 | /// Returns a copy of the arguments with a different type of decoding for 157 | /// selective decompilation. 158 | /// 159 | DecompilationArguments DecompilationArguments::withSelDecompDecoding( 160 | const std::string &decoding) { 161 | return withArgument(SelDecompDecodingId, decoding); 162 | } 163 | 164 | /// 165 | /// Is the type of decoding for selective decompilation set? 166 | /// 167 | bool DecompilationArguments::hasSelDecompDecoding() const { 168 | return hasArgument(SelDecompDecodingId); 169 | } 170 | 171 | /// 172 | /// Returns the type of decoding for selective decompilation. 173 | /// 174 | std::string DecompilationArguments::selDecompDecoding() const { 175 | return argument(SelDecompDecodingId); 176 | } 177 | 178 | /// 179 | /// Sets the input file. 180 | /// 181 | DecompilationArguments &DecompilationArguments::inputFile( 182 | const std::shared_ptr &file) { 183 | return this->file(InputFileId, file); 184 | } 185 | 186 | /// 187 | /// Returns a copy of the arguments with a different input file. 188 | /// 189 | DecompilationArguments DecompilationArguments::withInputFile( 190 | const std::shared_ptr &file) const { 191 | return withFile(InputFileId, file); 192 | } 193 | 194 | /// 195 | /// Is the input file set? 196 | /// 197 | bool DecompilationArguments::hasInputFile() const { 198 | return hasFile(InputFileId); 199 | } 200 | 201 | /// 202 | /// Returns the input file. 203 | /// 204 | std::shared_ptr DecompilationArguments::inputFile() const { 205 | return file(InputFileId); 206 | } 207 | 208 | /// 209 | /// Sets the argument of the given ID to the given value. 210 | /// 211 | DecompilationArguments &DecompilationArguments::argument( 212 | const std::string &id, const std::string &value) { 213 | return static_cast( 214 | ResourceArguments::argument(id, value) 215 | ); 216 | } 217 | 218 | /// 219 | /// Returns a copy of the arguments with a differing argument of the given ID. 220 | /// 221 | DecompilationArguments DecompilationArguments::withArgument( 222 | const std::string &id, const std::string &value) const { 223 | auto copy = *this; 224 | copy.argument(id, value); 225 | return copy; 226 | } 227 | 228 | /// 229 | /// Sets the file of the given ID to the given value. 230 | /// 231 | DecompilationArguments &DecompilationArguments::file( 232 | const std::string &id, const std::shared_ptr &file) { 233 | return static_cast( 234 | ResourceArguments::file(id, file) 235 | ); 236 | } 237 | 238 | /// 239 | /// Returns a copy of the files with a differing file of the given ID. 240 | /// 241 | DecompilationArguments DecompilationArguments::withFile( 242 | const std::string &id, const std::shared_ptr &file) const { 243 | auto copy = *this; 244 | copy.file(id, file); 245 | return copy; 246 | } 247 | 248 | } // namespace retdec 249 | -------------------------------------------------------------------------------- /src/retdec/decompiler.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/decompiler.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the decompilation service. 6 | /// 7 | 8 | #include "retdec/decompilation.h" 9 | #include "retdec/decompilation_arguments.h" 10 | #include "retdec/decompiler.h" 11 | #include "retdec/internal/connection_managers/real_connection_manager.h" 12 | #include "retdec/internal/service_with_resources_impl.h" 13 | #include "retdec/settings.h" 14 | 15 | using namespace retdec::internal; 16 | 17 | namespace retdec { 18 | namespace internal { 19 | 20 | /// 21 | /// Private implementation of Decompiler. 22 | /// 23 | class DecompilerImpl: public ServiceWithResourcesImpl { 24 | public: 25 | DecompilerImpl(const Settings &settings, 26 | const std::shared_ptr &connectionManager); 27 | virtual ~DecompilerImpl() override; 28 | }; 29 | 30 | /// 31 | /// Constructs a private implementation. 32 | /// 33 | /// @param[in] settings Settings for the service. 34 | /// @param[in] connectionManager Manager of connections. 35 | /// 36 | DecompilerImpl::DecompilerImpl(const Settings &settings, 37 | const std::shared_ptr &connectionManager): 38 | ServiceWithResourcesImpl( 39 | settings, 40 | connectionManager, 41 | "decompiler", 42 | "decompilations" 43 | ) {} 44 | 45 | // Override. 46 | DecompilerImpl::~DecompilerImpl() = default; 47 | 48 | } // namespace internal 49 | 50 | /// 51 | /// Constructs a decompiler with the given settings. 52 | /// 53 | Decompiler::Decompiler(const Settings &settings): 54 | Decompiler(settings, std::make_shared()) {} 55 | 56 | /// 57 | /// Constructs a decompiler with the given settings and connection manager. 58 | /// 59 | Decompiler::Decompiler(const Settings &settings, 60 | // The qualification in ::ConnectionManager below has to be be used due 61 | // to Doxygen limitations. 62 | const std::shared_ptr<::ConnectionManager> &connectionManager): 63 | Service(std::make_unique(settings, connectionManager)) {} 64 | 65 | // Override. 66 | Decompiler::~Decompiler() = default; 67 | 68 | /// 69 | /// Runs a new decompilation with the given arguments. 70 | /// 71 | std::unique_ptr Decompiler::runDecompilation( 72 | const DecompilationArguments &args) { 73 | return impl()->runResource(args); 74 | } 75 | 76 | /// 77 | /// Returns a properly cast private implementation. 78 | /// 79 | DecompilerImpl *Decompiler::impl() noexcept { 80 | return static_cast(pimpl.get()); 81 | } 82 | 83 | /// 84 | /// Constant overload of impl(). 85 | /// 86 | const DecompilerImpl *Decompiler::impl() const noexcept { 87 | return static_cast(pimpl.get()); 88 | } 89 | 90 | } // namespace retdec 91 | -------------------------------------------------------------------------------- /src/retdec/exceptions.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/exceptions.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the exceptions. 6 | /// 7 | 8 | #include "retdec/exceptions.h" 9 | 10 | namespace retdec { 11 | 12 | /// 13 | /// Creates an exception. 14 | /// 15 | /// @param[in] code Error code. 16 | /// @param[in] message Short message describing the error. 17 | /// @param[in] description Full description of the error. 18 | /// 19 | ApiError::ApiError(int code, const std::string &message, 20 | const std::string &description): 21 | Error(std::to_string(code) + " " + message), 22 | code(code), 23 | message(message), 24 | description(description) {} 25 | 26 | /// 27 | /// Returns the error code. 28 | /// 29 | int ApiError::getCode() const noexcept { 30 | return code; 31 | } 32 | 33 | /// 34 | /// Returns a short message describing the error. 35 | /// 36 | std::string ApiError::getMessage() const { 37 | return message; 38 | } 39 | 40 | /// 41 | /// Returns a full description of the error (if any). 42 | /// 43 | /// If there is no description, it returns the same value as @c what(). 44 | /// 45 | std::string ApiError::getDescription() const { 46 | return !description.empty() ? description : what(); 47 | } 48 | 49 | } // namespace retdec 50 | -------------------------------------------------------------------------------- /src/retdec/file.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/file.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the representation and factory for files. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/file.h" 11 | #include "retdec/internal/files/filesystem_file.h" 12 | #include "retdec/internal/files/string_file.h" 13 | 14 | using namespace retdec::internal; 15 | 16 | namespace retdec { 17 | 18 | /// 19 | /// Constructs a file. 20 | /// 21 | File::File() = default; 22 | 23 | /// 24 | /// Destructs the file. 25 | /// 26 | File::~File() = default; 27 | 28 | /// @fn File::getName() 29 | /// 30 | /// Returns the name of the file. 31 | /// 32 | /// When the file has no name, the empty string is returned. 33 | /// 34 | 35 | /// @fn File::getContent() 36 | /// 37 | /// Returns the content of the file. 38 | /// 39 | 40 | /// @fn File::saveCopyTo(const std::string &directoryPath) 41 | /// 42 | /// Stores a copy of the file into the given directory. 43 | /// 44 | 45 | /// @fn File::saveCopyTo(const std::string &directoryPath, 46 | /// const std::string &name) 47 | /// 48 | /// Stores a copy of the file into the given directory under the given name. 49 | /// 50 | 51 | /// 52 | /// Returns a file containing the given content with the given name. 53 | /// 54 | /// @param[in] content Content of the file. 55 | /// @param[in] name Name of the file. 56 | /// 57 | std::unique_ptr File::fromContentWithName(const std::string &content, 58 | const std::string &name) { 59 | return std::make_unique(content, name); 60 | } 61 | 62 | /// 63 | /// Returns a file from the given path. 64 | /// 65 | /// @param[in] path Path to the file. 66 | /// 67 | /// The name of the file is obtained automatically. 68 | /// 69 | std::unique_ptr File::fromFilesystem(const std::string &path) { 70 | return std::make_unique(path); 71 | } 72 | 73 | /// 74 | /// Returns a file from the given path, but with a custom name. 75 | /// 76 | /// @param[in] path Path to the file. 77 | /// @param[in] name Name to be used as the file's name. 78 | /// 79 | /// Use this function only if you want to choose a different name for the file 80 | /// than the one it already has. 81 | /// 82 | std::unique_ptr File::fromFilesystemWithOtherName( 83 | const std::string &path, const std::string &name) { 84 | return std::make_unique(path, name); 85 | } 86 | 87 | } // namespace retdec 88 | -------------------------------------------------------------------------------- /src/retdec/fileinfo.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/fileinfo.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the fileinfo service. 6 | /// 7 | 8 | #include "retdec/analysis.h" 9 | #include "retdec/analysis_arguments.h" 10 | #include "retdec/fileinfo.h" 11 | #include "retdec/internal/connection_managers/real_connection_manager.h" 12 | #include "retdec/internal/service_with_resources_impl.h" 13 | #include "retdec/settings.h" 14 | 15 | using namespace retdec::internal; 16 | 17 | namespace retdec { 18 | namespace internal { 19 | 20 | /// 21 | /// Private implementation of Fileinfo. 22 | /// 23 | class FileinfoImpl: public ServiceWithResourcesImpl { 24 | public: 25 | FileinfoImpl(const Settings &settings, 26 | const std::shared_ptr &connectionManager); 27 | virtual ~FileinfoImpl() override; 28 | }; 29 | 30 | /// 31 | /// Constructs a private implementation. 32 | /// 33 | /// @param[in] settings Settings for the service. 34 | /// @param[in] connectionManager Manager of connections. 35 | /// 36 | FileinfoImpl::FileinfoImpl(const Settings &settings, 37 | const std::shared_ptr &connectionManager): 38 | ServiceWithResourcesImpl( 39 | settings, 40 | connectionManager, 41 | "fileinfo", 42 | "analyses" 43 | ) {} 44 | 45 | // Override. 46 | FileinfoImpl::~FileinfoImpl() = default; 47 | 48 | } // namespace internal 49 | 50 | /// 51 | /// Constructs a fileinfo with the given settings. 52 | /// 53 | Fileinfo::Fileinfo(const Settings &settings): 54 | Fileinfo(settings, std::make_shared()) {} 55 | 56 | /// 57 | /// Constructs a fileinfo with the given settings and connection manager. 58 | /// 59 | Fileinfo::Fileinfo(const Settings &settings, 60 | // The qualification in ::ConnectionManager below has to be be used due 61 | // to Doxygen limitations. 62 | const std::shared_ptr<::ConnectionManager> &connectionManager): 63 | Service(std::make_unique(settings, connectionManager)) {} 64 | 65 | // Override. 66 | Fileinfo::~Fileinfo() = default; 67 | 68 | /// 69 | /// Runs a new analysis with the given arguments. 70 | /// 71 | std::unique_ptr Fileinfo::runAnalysis(const AnalysisArguments &args) { 72 | return impl()->runResource(args); 73 | } 74 | 75 | /// 76 | /// Returns a properly cast private implementation. 77 | /// 78 | FileinfoImpl *Fileinfo::impl() noexcept { 79 | return static_cast(pimpl.get()); 80 | } 81 | 82 | /// 83 | /// Constant overload of impl(). 84 | /// 85 | const FileinfoImpl *Fileinfo::impl() const noexcept { 86 | return static_cast(pimpl.get()); 87 | } 88 | 89 | } // namespace retdec 90 | -------------------------------------------------------------------------------- /src/retdec/internal/connection.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connection.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the base class of connections to the API. 6 | /// 7 | 8 | #include "retdec/internal/connection.h" 9 | 10 | namespace retdec { 11 | namespace internal { 12 | 13 | /// 14 | /// Constructs a response. 15 | /// 16 | Connection::Response::Response() = default; 17 | 18 | /// 19 | /// Destructs the response. 20 | /// 21 | Connection::Response::~Response() = default; 22 | 23 | /// @fn Connection::Response::statusCode() 24 | /// 25 | /// Returns the status code. 26 | /// 27 | 28 | /// @fn Connection::Response::statusMessage() 29 | /// 30 | /// Returns the status message. 31 | /// 32 | 33 | /// @fn Connection::Response::body() 34 | /// 35 | /// Returns the body of the response (raw). 36 | /// 37 | 38 | /// @fn Connection::Response::bodyAsJson() 39 | /// 40 | /// Returns the body of the response as JSON. 41 | /// 42 | 43 | /// @fn Connection::Response::bodyAsFile() 44 | /// 45 | /// Returns the body of the response as a file. 46 | /// 47 | 48 | /// 49 | /// Constructs a connection. 50 | /// 51 | Connection::Connection() = default; 52 | 53 | /// 54 | /// Destructs the connection. 55 | /// 56 | Connection::~Connection() = default; 57 | 58 | /// @fn Connection::getApiUrl() 59 | /// 60 | /// Returns the API URL to which this connection is connected. 61 | /// 62 | 63 | /// @fn std::unique_ptr Connection::sendGetRequest(const Url &url) 64 | /// 65 | /// Sends a GET request to the API and returns the response. 66 | /// 67 | /// @param[in] url URL to which the request is sent. 68 | /// 69 | 70 | /// @fn std::unique_ptr Connection::sendGetRequest(const Url &url, 71 | /// const RequestArguments &args) 72 | /// 73 | /// Sends a GET request with arguments to the API and returns the response. 74 | /// 75 | /// @param[in] url URL to which the request is sent. 76 | /// @param[in] args Arguments passed to the request. 77 | /// 78 | 79 | /// @fn Connection::sendPostRequest() 80 | /// 81 | /// Sends a POST request to the API and returns the response. 82 | /// 83 | /// @param[in] url URL to which the request is sent. 84 | /// @param[in] args Arguments passed in the request. 85 | /// @param[in] files Files passed in the request. 86 | /// 87 | 88 | } // namespace internal 89 | } // namespace retdec 90 | -------------------------------------------------------------------------------- /src/retdec/internal/connection_manager.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connection_manager.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the base class of connection managers. 6 | /// 7 | 8 | #include "retdec/internal/connection_manager.h" 9 | 10 | namespace retdec { 11 | namespace internal { 12 | 13 | /// 14 | /// Constructs a connection manager. 15 | /// 16 | ConnectionManager::ConnectionManager() = default; 17 | 18 | /// 19 | /// Destructs the connection manager. 20 | /// 21 | ConnectionManager::~ConnectionManager() = default; 22 | 23 | /// @fn ConnectionManager::newConnection() 24 | /// 25 | /// Creates a new connection. 26 | /// 27 | 28 | } // namespace internal 29 | } // namespace retdec 30 | -------------------------------------------------------------------------------- /src/retdec/internal/connection_managers/real_connection_manager.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connection_managers/real_connection_manager.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the manager of connections to the API. 6 | /// 7 | 8 | #include "retdec/internal/connection_managers/real_connection_manager.h" 9 | #include "retdec/internal/connections/real_connection.h" 10 | 11 | namespace retdec { 12 | namespace internal { 13 | 14 | /// 15 | /// Constructs a manager. 16 | /// 17 | RealConnectionManager::RealConnectionManager() = default; 18 | 19 | // Override. 20 | RealConnectionManager::~RealConnectionManager() = default; 21 | 22 | // Override. 23 | std::shared_ptr RealConnectionManager::newConnection(const Settings &settings) { 24 | return std::make_shared(settings); 25 | } 26 | 27 | } // namespace internal 28 | } // namespace retdec 29 | -------------------------------------------------------------------------------- /src/retdec/internal/files/filesystem_file.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/files/filesystem_file.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the file stored in a filesystem. 6 | /// 7 | 8 | #include "retdec/internal/files/filesystem_file.h" 9 | #include "retdec/internal/utilities/os.h" 10 | 11 | namespace retdec { 12 | namespace internal { 13 | 14 | /// 15 | /// Constructs a file. 16 | /// 17 | /// @param[in] path Path to the file in a filesystem. 18 | /// 19 | FilesystemFile::FilesystemFile(const std::string &path): 20 | path(path), name(fileNameFromPath(path)) {} 21 | 22 | /// 23 | /// Constructs a file with a custom name. 24 | /// 25 | /// @param[in] path Path to the file in a filesystem. 26 | /// @param[in] name Name to be used as the file's name. 27 | /// 28 | /// @par Preconditions 29 | /// - @a name is non-empty 30 | /// 31 | FilesystemFile::FilesystemFile(std::string path, std::string name): 32 | path(std::move(path)), name(std::move(name)) {} 33 | 34 | /// 35 | /// Destructs the file. 36 | /// 37 | FilesystemFile::~FilesystemFile() = default; 38 | 39 | // Override. 40 | std::string FilesystemFile::getName() const { 41 | return name; 42 | } 43 | 44 | // Override. 45 | std::string FilesystemFile::getContent() { 46 | return readFile(path); 47 | } 48 | 49 | // Override. 50 | void FilesystemFile::saveCopyTo(const std::string &directoryPath) { 51 | saveCopyTo(directoryPath, name); 52 | } 53 | 54 | // Override. 55 | void FilesystemFile::saveCopyTo(const std::string &directoryPath, 56 | const std::string &name) { 57 | copyFile(path, joinPaths(directoryPath, name)); 58 | } 59 | 60 | } // namespace internal 61 | } // namespace retdec 62 | -------------------------------------------------------------------------------- /src/retdec/internal/files/string_file.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/files/string_file.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the file storing its content in a string. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/files/string_file.h" 11 | #include "retdec/internal/utilities/os.h" 12 | 13 | namespace retdec { 14 | namespace internal { 15 | 16 | /// 17 | /// Constructs a file with the given content. 18 | /// 19 | StringFile::StringFile(std::string content): 20 | content(std::move(content)) {} 21 | 22 | /// 23 | /// Constructs a file with the given content and name. 24 | /// 25 | StringFile::StringFile(std::string content, std::string name): 26 | content(std::move(content)), name(std::move(name)) {} 27 | 28 | /// 29 | /// Destructs the file. 30 | /// 31 | StringFile::~StringFile() = default; 32 | 33 | // Override. 34 | std::string StringFile::getName() const { 35 | return name; 36 | } 37 | 38 | // Override. 39 | std::string StringFile::getContent() { 40 | return content; 41 | } 42 | 43 | // Override. 44 | void StringFile::saveCopyTo(const std::string &directoryPath) { 45 | saveCopyTo(directoryPath, name); 46 | } 47 | 48 | // Override. 49 | void StringFile::saveCopyTo(const std::string &directoryPath, 50 | const std::string &name) { 51 | writeFile(joinPaths(directoryPath, name), content); 52 | } 53 | 54 | } // namespace internal 55 | } // namespace retdec 56 | -------------------------------------------------------------------------------- /src/retdec/internal/resource_impl.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/resource_impl.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the base class of private resource 6 | /// implementations. 7 | /// 8 | 9 | #include "retdec/internal/resource_impl.h" 10 | #include "retdec/internal/utilities/connection.h" 11 | 12 | namespace retdec { 13 | namespace internal { 14 | 15 | /// 16 | /// Constructs a private implementation. 17 | /// 18 | /// @param[in] id Identifier of the resource. 19 | /// @param[in] conn Connection to be used to communicate with the API. 20 | /// @param[in] serviceName Name of the service. 21 | /// @param[in] resourcesName Name of the resources (plural). 22 | /// 23 | ResourceImpl::ResourceImpl( 24 | const std::string &id, 25 | const std::shared_ptr &conn, 26 | const std::string &serviceName, 27 | const std::string &resourcesName 28 | ): 29 | id(id), 30 | conn(std::make_shared(conn)), 31 | baseUrl(conn->getApiUrl() + "/" + serviceName + "/" + resourcesName + "/" + id), 32 | statusUrl(baseUrl + "/status") 33 | {} 34 | 35 | /// 36 | /// Destructs the private implementation. 37 | /// 38 | ResourceImpl::~ResourceImpl() = default; 39 | 40 | /// 41 | /// Should the status be updated? 42 | /// 43 | bool ResourceImpl::shouldUpdateStatus() { 44 | return !finished; 45 | } 46 | 47 | /// 48 | /// Updates the status of the resource. 49 | /// 50 | void ResourceImpl::updateStatus() { 51 | auto response = conn->sendGetRequest(statusUrl); 52 | auto jsonBody = response->bodyAsJson(); 53 | finished = jsonBody.get("finished", false).asBool(); 54 | succeeded = jsonBody.get("succeeded", false).asBool(); 55 | failed = jsonBody.get("failed", false).asBool(); 56 | error = jsonBody.get("error", "").asString(); 57 | updateResourceSpecificStatus(jsonBody); 58 | } 59 | 60 | /// 61 | /// Updates the status (if needed). 62 | /// 63 | void ResourceImpl::updateStatusIfNeeded() { 64 | if (shouldUpdateStatus()) { 65 | updateStatus(); 66 | } 67 | } 68 | 69 | /// 70 | /// Updates resource-specific parts of the status. 71 | /// 72 | /// If not overridden, it does nothing. 73 | /// 74 | void ResourceImpl::updateResourceSpecificStatus(const Json::Value &) {} 75 | 76 | } // namespace internal 77 | } // namespace retdec 78 | -------------------------------------------------------------------------------- /src/retdec/internal/service_impl.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/service_impl.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the base class of private service 6 | /// implementations. 7 | /// 8 | 9 | #include "retdec/internal/service_impl.h" 10 | #include "retdec/resource_arguments.h" 11 | 12 | namespace retdec { 13 | namespace internal { 14 | 15 | /// 16 | /// Constructs a private implementation. 17 | /// 18 | /// @param[in] settings Settings for the service. 19 | /// @param[in] connectionManager Manager of connections. 20 | /// @param[in] serviceName Name of the service. 21 | /// 22 | ServiceImpl::ServiceImpl(const Settings &settings, 23 | const std::shared_ptr &connectionManager, 24 | const std::string &serviceName): 25 | settings(settings), 26 | connectionManager(connectionManager), 27 | baseUrl(settings.apiUrl() + "/" + serviceName) {} 28 | 29 | /// 30 | /// Destructs the private implementation. 31 | /// 32 | ServiceImpl::~ServiceImpl() = default; 33 | 34 | /// 35 | /// Constructs Connection::RequestArguments from the given resource arguments. 36 | /// 37 | Connection::RequestArguments ServiceImpl::createRequestArguments( 38 | const ResourceArguments &args) const { 39 | return Connection::RequestArguments( 40 | args.argumentsBegin(), args.argumentsEnd() 41 | ); 42 | } 43 | 44 | /// 45 | /// Constructs Connection::RequestFiles from the given resource arguments. 46 | /// 47 | Connection::RequestFiles ServiceImpl::createRequestFiles( 48 | const ResourceArguments &args) const { 49 | return Connection::RequestFiles( 50 | args.filesBegin(), args.filesEnd() 51 | ); 52 | } 53 | 54 | } // namespace internal 55 | } // namespace retdec 56 | -------------------------------------------------------------------------------- /src/retdec/internal/service_with_resources_impl.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/service_with_resources_impl.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the base class of private implementations of 6 | /// services with resources. 7 | /// 8 | 9 | #include "retdec/internal/service_with_resources_impl.h" 10 | 11 | namespace retdec { 12 | namespace internal { 13 | 14 | /// 15 | /// Constructs a private implementation. 16 | /// 17 | /// @param[in] settings Settings for the service. 18 | /// @param[in] connectionManager Manager of connections. 19 | /// @param[in] serviceName Name of the service. 20 | /// @param[in] resourcesName Name of the resources (plural). 21 | /// 22 | ServiceWithResourcesImpl::ServiceWithResourcesImpl(const Settings &settings, 23 | const std::shared_ptr &connectionManager, 24 | const std::string &serviceName, 25 | const std::string &resourcesName): 26 | ServiceImpl(settings, connectionManager, serviceName), 27 | resourcesUrl(baseUrl + "/" + resourcesName) {} 28 | 29 | /// 30 | /// Destructs the private implementation. 31 | /// 32 | ServiceWithResourcesImpl::~ServiceWithResourcesImpl() = default; 33 | 34 | } // namespace internal 35 | } // namespace retdec 36 | -------------------------------------------------------------------------------- /src/retdec/internal/utilities/connection.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/connection.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the connection utilities. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/exceptions.h" 11 | #include "retdec/internal/utilities/connection.h" 12 | #include "retdec/internal/utilities/json.h" 13 | 14 | namespace retdec { 15 | namespace internal { 16 | 17 | namespace { 18 | 19 | /// 20 | /// Throws ApiError or its subclass, depending on @a code. 21 | /// 22 | void throwApiError(int code, const std::string &message, 23 | const std::string &description = "") { 24 | if (code == 401) { 25 | throw AuthError(code, message, description); 26 | } 27 | throw ApiError(code, message, description); 28 | } 29 | 30 | } // anonymous namespace 31 | 32 | /// 33 | /// Checks if a request resulted in the given @a response succeeded. 34 | /// 35 | bool requestSucceeded(const Connection::Response &response) { 36 | // Status codes other than 2xx signalize a failure. 37 | auto code = response.statusCode(); 38 | return code >= 200 && code <= 299; 39 | } 40 | 41 | /// 42 | /// Verifies that a request resulted in the given @a response succeeded. 43 | /// 44 | /// @throws ApiError When the request failed. 45 | /// 46 | void verifyRequestSucceeded(const Connection::Response &response) { 47 | if (!requestSucceeded(response)) { 48 | try { 49 | auto jsonBody = response.bodyAsJson(); 50 | return throwApiError( 51 | jsonBody.get("code", response.statusCode()).asInt(), 52 | jsonBody.get("message", response.statusMessage()).asString(), 53 | jsonBody.get("description", "").asString() 54 | ); 55 | } catch (const JsonDecodingError &) { 56 | return throwApiError( 57 | response.statusCode(), 58 | response.statusMessage() 59 | ); 60 | } 61 | } 62 | } 63 | 64 | /// 65 | /// Creates a verifying connection by wrapping a connection. 66 | /// 67 | ResponseVerifyingConnection::ResponseVerifyingConnection( 68 | const std::shared_ptr &conn): 69 | conn(conn) {} 70 | 71 | /// 72 | /// Destructs the connection. 73 | /// 74 | ResponseVerifyingConnection::~ResponseVerifyingConnection() {} 75 | 76 | // Override. 77 | Connection::Url ResponseVerifyingConnection::getApiUrl() const { 78 | return conn->getApiUrl(); 79 | } 80 | 81 | // Override. 82 | std::unique_ptr ResponseVerifyingConnection::sendGetRequest( 83 | const Url &url) { 84 | auto response = conn->sendGetRequest(url); 85 | verifyRequestSucceeded(*response); 86 | return response; 87 | } 88 | 89 | // Override. 90 | std::unique_ptr ResponseVerifyingConnection::sendGetRequest( 91 | const Connection::Url &url, const RequestArguments &args) { 92 | auto response = conn->sendGetRequest(url, args); 93 | verifyRequestSucceeded(*response); 94 | return response; 95 | } 96 | 97 | // Override. 98 | std::unique_ptr ResponseVerifyingConnection::sendPostRequest( 99 | const Url &url, const RequestArguments &args, 100 | const RequestFiles &files) { 101 | auto response = conn->sendPostRequest(url, args, files); 102 | verifyRequestSucceeded(*response); 103 | return response; 104 | } 105 | 106 | } // namespace internal 107 | } // namespace retdec 108 | -------------------------------------------------------------------------------- /src/retdec/internal/utilities/json.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/json.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the JSON utility functions. 6 | /// 7 | 8 | #include "retdec/exceptions.h" 9 | #include "retdec/internal/utilities/json.h" 10 | 11 | namespace retdec { 12 | namespace internal { 13 | 14 | /// 15 | /// Creates an exception. 16 | /// 17 | /// @param[in] formattedErrors Formatted error messages. 18 | /// 19 | JsonDecodingError::JsonDecodingError(const std::string &formattedErrors): 20 | Error("JSON decoding failed: " + formattedErrors) {} 21 | 22 | /// 23 | /// Decodes the given string into a JSON value. 24 | /// 25 | /// @throws JsonDecodingError When the decoding fails, i.e. @a str is not valid 26 | /// JSON. 27 | /// 28 | Json::Value toJson(const std::string &str) { 29 | Json::Value strAsJson; 30 | Json::Reader reader; 31 | bool parsingSuccessful = reader.parse(str, strAsJson); 32 | if (!parsingSuccessful) { 33 | throw JsonDecodingError(reader.getFormattedErrorMessages()); 34 | } 35 | return strAsJson; 36 | } 37 | 38 | } // namespace internal 39 | } // namespace retdec 40 | -------------------------------------------------------------------------------- /src/retdec/internal/utilities/os.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/os.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the operating-system-related utilities. 6 | /// 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "retdec/exceptions.h" 15 | #include "retdec/internal/utilities/os.h" 16 | 17 | using namespace std::string_literals; 18 | 19 | namespace retdec { 20 | namespace internal { 21 | 22 | /// 23 | /// Returns a name of the operating system. 24 | /// 25 | /// If the name cannot be determined, it returns @c "Unknown". 26 | /// 27 | std::string operatingSystemName() { 28 | #if defined(RETDEC_OS_WINDOWS) 29 | return "Windows"; 30 | #elif defined(RETDEC_OS_ANDROID) 31 | return "Android"; 32 | #elif defined(RETDEC_OS_LINUX) 33 | return "Linux"; 34 | #elif defined(RETDEC_OS_MACOS) 35 | return "MacOS"; 36 | #elif defined(RETDEC_OS_BSD) 37 | return "BSD"; 38 | #elif defined(RETDEC_OS_UNIX) 39 | return "UNIX"; 40 | #else 41 | return "Unknown"; 42 | #endif 43 | } 44 | 45 | /// 46 | /// Returns the file name from the given path. 47 | /// 48 | /// @param[in] path Path to the file. 49 | /// 50 | /// If there is no file name, it returns the empty string. 51 | /// 52 | std::string fileNameFromPath(const std::string &path) { 53 | // For a path without a filename, boost::filesystem::path::filename() 54 | // returns ".", but we want to return the empty string in such a case. 55 | auto fileName = boost::filesystem::path(path).filename().string(); 56 | return fileName != "." ? fileName : ""s; 57 | } 58 | 59 | /// 60 | /// Joins the given two paths. 61 | /// 62 | std::string joinPaths(const std::string &path1, const std::string &path2) { 63 | boost::filesystem::path joined(path1); 64 | joined /= path2; 65 | return joined.string(); 66 | } 67 | 68 | /// 69 | /// Returns the content of the given file. 70 | /// 71 | /// @param[in] path Path to the file. 72 | /// 73 | /// @throws FilesystemError When the file cannot be opened or read. 74 | /// 75 | /// The file is opened in the binary mode, so no conversions are performed 76 | /// during the reading. 77 | /// 78 | std::string readFile(const std::string &path) { 79 | std::ifstream file(path, std::ios::in | std::ios::binary); 80 | if (!file) { 81 | throw FilesystemError("cannot open file \"" + path + "\""); 82 | } 83 | 84 | file.exceptions(std::ifstream::failbit | std::ifstream::badbit); 85 | std::string content; 86 | try { 87 | // The following method gets the file size, resizes the string holding 88 | // the content, and reads the file afterwards. The obtained file size 89 | // is reliable because we have opened the file in the binary mode, so 90 | // there are no conversions performed. 91 | file.seekg(0, std::ios::end); 92 | content.resize(file.tellg()); 93 | file.seekg(0, std::ios::beg); 94 | file.read(&content[0], content.size()); 95 | } catch (const std::ifstream::failure &) { 96 | throw FilesystemError("cannot read file \"" + path + "\""); 97 | } 98 | return content; 99 | } 100 | 101 | /// 102 | /// Stores a file with the given @a content into the given @a path. 103 | /// 104 | /// @throws FilesystemError When the file cannot be opened or written. 105 | /// 106 | /// The file is opened in the binary mode, so no conversions are performed 107 | /// during writing. 108 | /// 109 | void writeFile(const std::string &path, const std::string &content) { 110 | std::ofstream file(path, std::ios::out | std::ios::binary); 111 | if (!file) { 112 | throw FilesystemError("cannot open file \"" + path + "\""); 113 | } 114 | 115 | file << content; 116 | if (!file) { 117 | throw FilesystemError("cannot write file \"" + path + "\""); 118 | } 119 | } 120 | 121 | /// 122 | /// Copies file in @a srcPath to a file in @a dstPath. 123 | /// 124 | /// @throws FilesystemError When a file cannot be opened, read, or written. 125 | /// 126 | void copyFile(const std::string &srcPath, const std::string &dstPath) { 127 | try { 128 | boost::filesystem::copy_file(srcPath, dstPath, 129 | boost::filesystem::copy_option::overwrite_if_exists); 130 | } catch (const boost::filesystem::filesystem_error &) { 131 | throw FilesystemError("cannot copy file \"" + srcPath + 132 | "\" to \"" + dstPath + "\""); 133 | } 134 | } 135 | 136 | /// 137 | /// Sleeps for the given number of milliseconds. 138 | /// 139 | void sleep(int milliseconds) { 140 | // Do not use std::this_thread::sleep_for() because is not 141 | // available in MinGW on Windows. 142 | boost::this_thread::sleep(boost::posix_time::milliseconds(milliseconds)); 143 | } 144 | 145 | } // namespace internal 146 | } // namespace retdec 147 | -------------------------------------------------------------------------------- /src/retdec/internal/utilities/string.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/string.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the string utility functions. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/utilities/string.h" 11 | 12 | namespace retdec { 13 | namespace internal { 14 | 15 | /// 16 | /// Capitalizes all words in the given string. 17 | /// 18 | /// Example: 19 | /// @code 20 | /// capitalizeWords("my name is jerry") // -> "My Name Is Jerry" 21 | /// capitalizeWords("MY NAME IS JERRY") // -> "My Name Is Jerry" 22 | /// @endcode 23 | // 24 | std::string capitalizeWords(std::string s) { 25 | bool capitalizeNext = true; 26 | for (auto &c : s) { 27 | if (std::isspace(c)) { 28 | capitalizeNext = true; 29 | } else if (std::isalpha(c)) { 30 | c = capitalizeNext ? std::toupper(c) : std::tolower(c); 31 | capitalizeNext = false; 32 | } else { 33 | capitalizeNext = false; 34 | } 35 | } 36 | return s; 37 | } 38 | 39 | } // namespace internal 40 | } // namespace retdec 41 | -------------------------------------------------------------------------------- /src/retdec/resource.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/resource.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the base class of all resources. 6 | /// 7 | 8 | #include "retdec/internal/resource_impl.h" 9 | #include "retdec/resource.h" 10 | 11 | namespace retdec { 12 | 13 | /// 14 | /// Constructs a resource. 15 | /// 16 | Resource::Resource(std::unique_ptr impl): 17 | pimpl(std::move(impl)) {} 18 | 19 | /// 20 | /// Destructs the resource. 21 | /// 22 | Resource::~Resource() = default; 23 | 24 | /// 25 | /// Returns the ID of the resource. 26 | /// 27 | /// Does not access the API. 28 | /// 29 | std::string Resource::getId() const { 30 | return pimpl->id; 31 | } 32 | 33 | /// 34 | /// Has the resource finished? 35 | /// 36 | /// May access the API. 37 | /// 38 | bool Resource::hasFinished() { 39 | pimpl->updateStatusIfNeeded(); 40 | return pimpl->finished; 41 | } 42 | 43 | /// 44 | /// Has the resource finished? 45 | /// 46 | /// Does not access the API. 47 | /// 48 | bool Resource::hasFinished() const noexcept { 49 | return pimpl->finished; 50 | } 51 | 52 | /// 53 | /// Has the resource succeeded? 54 | /// 55 | /// The output from this function is meaningful only if hasFinished() returns 56 | /// @c true. 57 | /// 58 | /// May access the API. 59 | /// 60 | bool Resource::hasSucceeded() { 61 | pimpl->updateStatusIfNeeded(); 62 | return pimpl->succeeded; 63 | } 64 | 65 | /// 66 | /// Has the resource succeeded? 67 | /// 68 | /// The output from this function is meaningful only if hasFinished() returns 69 | /// @c true. 70 | /// 71 | /// Does not access the API. 72 | /// 73 | bool Resource::hasSucceeded() const noexcept { 74 | return pimpl->succeeded; 75 | } 76 | 77 | /// 78 | /// Has the resource failed? 79 | /// 80 | /// The output from this function is meaningful only if hasFinished() returns 81 | /// @c true. 82 | /// 83 | /// May access the API. 84 | /// 85 | bool Resource::hasFailed() { 86 | pimpl->updateStatusIfNeeded(); 87 | return pimpl->failed; 88 | } 89 | 90 | /// 91 | /// Has the resource failed? 92 | /// 93 | /// The output from this function is meaningful only if hasFinished() returns 94 | /// @c true. 95 | /// 96 | /// Does not access the API. 97 | /// 98 | bool Resource::hasFailed() const noexcept { 99 | return pimpl->failed; 100 | } 101 | 102 | /// 103 | /// Returns the error message (if any). 104 | /// 105 | /// The output from this function is meaningful only if hasFinished() returns 106 | /// @c true and hasFailed() returns @c true. 107 | /// 108 | /// May access the API. 109 | /// 110 | std::string Resource::getError() { 111 | pimpl->updateStatusIfNeeded(); 112 | return pimpl->error; 113 | } 114 | 115 | /// 116 | /// Returns the error message (if any). 117 | /// 118 | /// The output from this function is meaningful only if hasFinished() returns 119 | /// @c true and hasFailed() returns @c true. 120 | /// 121 | /// Does not access the API. 122 | /// 123 | std::string Resource::getError() const { 124 | return pimpl->error; 125 | } 126 | 127 | } // namespace retdec 128 | -------------------------------------------------------------------------------- /src/retdec/resource_arguments.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/resource_arguments.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the base class of arguments for all services. 6 | /// 7 | 8 | #include "retdec/internal/utilities/container.h" 9 | #include "retdec/resource_arguments.h" 10 | 11 | using namespace retdec::internal; 12 | 13 | namespace retdec { 14 | 15 | /// 16 | /// Constructs default arguments. 17 | /// 18 | ResourceArguments::ResourceArguments() = default; 19 | 20 | /// 21 | /// Copy-constructs arguments from the given arguments. 22 | /// 23 | ResourceArguments::ResourceArguments( 24 | const ResourceArguments &) = default; 25 | 26 | /// 27 | /// Move-constructs arguments from the given arguments. 28 | /// 29 | ResourceArguments::ResourceArguments( 30 | ResourceArguments &&) = default; 31 | 32 | /// 33 | /// Copy-assigns the given arguments. 34 | /// 35 | ResourceArguments &ResourceArguments::operator=( 36 | const ResourceArguments &) = default; 37 | 38 | /// 39 | /// Move-assigns the given arguments. 40 | /// 41 | ResourceArguments &ResourceArguments::operator=( 42 | ResourceArguments &&) = default; 43 | 44 | /// 45 | /// Destructs the arguments. 46 | /// 47 | ResourceArguments::~ResourceArguments() = default; 48 | 49 | /// 50 | /// Sets the argument of the given ID to the given value. 51 | /// 52 | ResourceArguments &ResourceArguments::argument( 53 | const std::string &id, const std::string &value) { 54 | arguments[id] = value; 55 | return *this; 56 | } 57 | 58 | /// 59 | /// Returns a copy of the arguments with a differing argument of the given ID. 60 | /// 61 | ResourceArguments ResourceArguments::withArgument( 62 | const std::string &id, const std::string &value) const { 63 | auto copy = *this; 64 | copy.argument(id, value); 65 | return copy; 66 | } 67 | 68 | /// 69 | /// Is an argument of the given ID present? 70 | /// 71 | bool ResourceArguments::hasArgument(const std::string &id) const { 72 | return hasKey(arguments, id); 73 | } 74 | 75 | /// 76 | /// Returns the value of the given argument. 77 | /// 78 | /// If there is no such argument, it returns the empty string. 79 | /// 80 | std::string ResourceArguments::argument(const std::string &id) const { 81 | return getValue(arguments, id); 82 | } 83 | 84 | /// 85 | /// Returns an iterator to the beginning of arguments. 86 | /// 87 | ResourceArguments::ArgumentIterator ResourceArguments::argumentsBegin() const { 88 | return arguments.begin(); 89 | } 90 | 91 | /// 92 | /// Returns an iterator past the last argument. 93 | /// 94 | ResourceArguments::ArgumentIterator ResourceArguments::argumentsEnd() const { 95 | return arguments.end(); 96 | } 97 | 98 | /// 99 | /// Sets the file of the given ID to the given value. 100 | /// 101 | ResourceArguments &ResourceArguments::file( 102 | const std::string &id, const std::shared_ptr &file) { 103 | files[id] = file; 104 | return *this; 105 | } 106 | 107 | /// 108 | /// Returns a copy of the files with a differing file of the given ID. 109 | /// 110 | ResourceArguments ResourceArguments::withFile( 111 | const std::string &id, const std::shared_ptr &file) const { 112 | auto copy = *this; 113 | copy.file(id, file); 114 | return copy; 115 | } 116 | 117 | /// 118 | /// Is a file of the given ID present? 119 | /// 120 | bool ResourceArguments::hasFile(const std::string &id) const { 121 | return hasKey(files, id); 122 | } 123 | 124 | /// 125 | /// Returns the file of the given ID. 126 | /// 127 | /// If there is no such file, it returns the null pointer. 128 | /// 129 | std::shared_ptr ResourceArguments::file(const std::string &id) const { 130 | return getValue(files, id); 131 | } 132 | 133 | /// 134 | /// Returns an iterator to the beginning of arguments. 135 | /// 136 | ResourceArguments::FileIterator ResourceArguments::filesBegin() const { 137 | return files.begin(); 138 | } 139 | 140 | /// 141 | /// Returns an iterator past the last argument. 142 | /// 143 | ResourceArguments::FileIterator ResourceArguments::filesEnd() const { 144 | return files.end(); 145 | } 146 | 147 | } // namespace retdec 148 | -------------------------------------------------------------------------------- /src/retdec/retdec-config.cmake.in: -------------------------------------------------------------------------------- 1 | ## 2 | ## Project: retdec-cpp 3 | ## Copyright: (c) 2015 by Petr Zemek and contributors 4 | ## License: MIT, see the LICENSE file for more details 5 | ## 6 | ## Project's CMake configuration file for find_package(retdec). 7 | ## 8 | 9 | include("@INSTALL_LIB_CMAKE_DIR@/retdec.cmake") 10 | set(retdec_INCLUDE_DIRS @INSTALL_INCLUDE_DIR@) 11 | -------------------------------------------------------------------------------- /src/retdec/service.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/service.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the base class of all services. 6 | /// 7 | 8 | #include "retdec/internal/service_impl.h" 9 | #include "retdec/service.h" 10 | 11 | namespace retdec { 12 | 13 | /// 14 | /// Constructs a service. 15 | /// 16 | Service::Service(std::unique_ptr impl): 17 | pimpl(std::move(impl)) {} 18 | 19 | /// 20 | /// Destructs the service. 21 | /// 22 | Service::~Service() = default; 23 | 24 | } // namespace retdec 25 | -------------------------------------------------------------------------------- /src/retdec/settings.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/settings.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the library settings. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/utilities/os.h" 11 | #include "retdec/settings.h" 12 | 13 | using namespace retdec::internal; 14 | 15 | namespace retdec { 16 | 17 | /// 18 | /// Constructs a default settings. 19 | /// 20 | Settings::Settings(): 21 | apiUrl_(DefaultApiUrl), apiKey_(DefaultApiKey), 22 | userAgent_(DefaultUserAgent) {} 23 | 24 | /// 25 | /// Copy-constructs settings from the given settings. 26 | /// 27 | Settings::Settings(const Settings &) = default; 28 | 29 | /// 30 | /// Move-constructs settings from the given settings. 31 | /// 32 | Settings::Settings(Settings &&) = default; 33 | 34 | /// 35 | /// Copy-assigns the given settings. 36 | /// 37 | Settings &Settings::operator=(const Settings &) = default; 38 | 39 | /// 40 | /// Move-assigns the given settings. 41 | /// 42 | Settings &Settings::operator=(Settings &&) = default; 43 | 44 | /// 45 | /// Destructs the settings. 46 | /// 47 | Settings::~Settings() = default; 48 | 49 | /// 50 | /// Sets a new API key. 51 | /// 52 | /// @returns Reference to the modified settings (i.e. @c *this). 53 | /// 54 | Settings &Settings::apiKey(const std::string &apiKey) { 55 | apiKey_ = apiKey; 56 | return *this; 57 | } 58 | 59 | /// 60 | /// Returns a copy of the settings with a new API key. 61 | /// 62 | Settings Settings::withApiKey(const std::string &apiKey) const { 63 | auto copy = *this; 64 | copy.apiKey(apiKey); 65 | return copy; 66 | } 67 | 68 | /// 69 | /// Returns the API key. 70 | /// 71 | std::string Settings::apiKey() const { 72 | return apiKey_; 73 | } 74 | 75 | /// 76 | /// Sets a new URL to the API. 77 | /// 78 | /// @returns Reference to the modified settings (i.e. @c *this). 79 | /// 80 | Settings &Settings::apiUrl(const std::string &apiUrl) { 81 | apiUrl_ = apiUrl; 82 | return *this; 83 | } 84 | 85 | /// 86 | /// Returns a copy of the settings with a new URL to the API. 87 | /// 88 | Settings Settings::withApiUrl(const std::string &apiUrl) const { 89 | auto copy = *this; 90 | copy.apiUrl(apiUrl); 91 | return copy; 92 | } 93 | 94 | /// 95 | /// Returns the URL to the API. 96 | /// 97 | std::string Settings::apiUrl() const { 98 | return apiUrl_; 99 | } 100 | 101 | /// 102 | /// Sets a new user agent. 103 | /// 104 | /// @returns Reference to the modified settings (i.e. @c *this). 105 | /// 106 | Settings &Settings::userAgent(const std::string &userAgent) { 107 | userAgent_ = userAgent; 108 | return *this; 109 | } 110 | 111 | /// 112 | /// Returns a copy of the settings with a new user agent. 113 | /// 114 | Settings Settings::withUserAgent(const std::string &userAgent) const { 115 | auto copy = *this; 116 | copy.userAgent(userAgent); 117 | return copy; 118 | } 119 | 120 | /// 121 | /// Returns the user agent. 122 | /// 123 | std::string Settings::userAgent() const { 124 | return userAgent_; 125 | } 126 | 127 | /// Default URL to the API. 128 | const std::string Settings::DefaultApiUrl = "https://retdec.com/service/api"; 129 | 130 | /// Default API key. 131 | const std::string Settings::DefaultApiKey = ""; 132 | 133 | /// Default user agent. 134 | const std::string Settings::DefaultUserAgent = "retdec-cpp/" + 135 | operatingSystemName(); 136 | 137 | } // namespace retdec 138 | -------------------------------------------------------------------------------- /src/retdec/test.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/test.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the testing service. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/connection_managers/real_connection_manager.h" 11 | #include "retdec/internal/service_impl.h" 12 | #include "retdec/settings.h" 13 | #include "retdec/test.h" 14 | 15 | using namespace retdec::internal; 16 | 17 | namespace retdec { 18 | namespace internal { 19 | 20 | /// 21 | /// Private implementation of Test. 22 | /// 23 | class TestImpl: public ServiceImpl { 24 | public: 25 | TestImpl(const Settings &settings, 26 | const std::shared_ptr &connectionManager); 27 | virtual ~TestImpl() override; 28 | 29 | /// URL to the @c echo sub-service. 30 | const std::string echoUrl; 31 | }; 32 | 33 | /// 34 | /// Constructs a private implementation. 35 | /// 36 | /// @param[in] settings Settings for the service. 37 | /// @param[in] connectionManager Manager of connections. 38 | /// 39 | TestImpl::TestImpl(const Settings &settings, 40 | const std::shared_ptr &connectionManager): 41 | ServiceImpl(settings, connectionManager, "test"), 42 | echoUrl(baseUrl + "/" + "echo") {} 43 | 44 | // Override. 45 | TestImpl::~TestImpl() = default; 46 | 47 | } // namespace internal 48 | 49 | /// 50 | /// Constructs a test with the given settings. 51 | /// 52 | Test::Test(const Settings &settings): 53 | Test(settings, std::make_shared()) {} 54 | 55 | /// 56 | /// Constructs a test with the given settings and connection manager. 57 | /// 58 | Test::Test(const Settings &settings, 59 | // The qualification in ::ConnectionManager below has to be be used due 60 | // to Doxygen limitations. 61 | const std::shared_ptr<::ConnectionManager> &connectionManager): 62 | Service(std::make_unique(settings, connectionManager)) {} 63 | 64 | // Override. 65 | Test::~Test() = default; 66 | 67 | /// 68 | /// Tries to authenticate. 69 | /// 70 | /// @throws AuthError When the authentication fails. 71 | /// 72 | /// Does nothing when the authentication succeeds. 73 | /// 74 | void Test::auth() { 75 | auto conn = impl()->connectionManager->newConnection(impl()->settings); 76 | // We do not need any parameters; simply send a GET request to /test/echo, 77 | // and if the authentication fails, AuthError will be automatically thrown. 78 | auto response = conn->sendGetRequest(impl()->echoUrl); 79 | verifyRequestSucceeded(*response); 80 | } 81 | 82 | /// 83 | /// Returns a properly cast private implementation. 84 | /// 85 | TestImpl *Test::impl() noexcept { 86 | return static_cast(pimpl.get()); 87 | } 88 | 89 | /// 90 | /// Constant overload of impl(). 91 | /// 92 | const TestImpl *Test::impl() const noexcept { 93 | return static_cast(pimpl.get()); 94 | } 95 | 96 | } // namespace retdec 97 | -------------------------------------------------------------------------------- /src/tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## 2 | ## Project: retdec-cpp 3 | ## Copyright: (c) 2015 by Petr Zemek and contributors 4 | ## License: MIT, see the LICENSE file for more details 5 | ## 6 | ## CMake configuration file for the tools. 7 | ## 8 | 9 | if(NOT RETDEC_TOOLS) 10 | return() 11 | endif() 12 | 13 | # Decompiler. 14 | 15 | set(DECOMPILER_SOURCES 16 | decompiler.cpp 17 | ) 18 | 19 | add_executable(decompiler ${DECOMPILER_SOURCES}) 20 | target_link_libraries(decompiler retdec) 21 | 22 | install(TARGETS decompiler DESTINATION "${INSTALL_BIN_DIR}") 23 | 24 | # Fileinfo. 25 | 26 | set(FILEINFO_SOURCES 27 | fileinfo.cpp 28 | ) 29 | 30 | add_executable(fileinfo ${FILEINFO_SOURCES}) 31 | target_link_libraries(fileinfo retdec) 32 | 33 | install(TARGETS fileinfo DESTINATION "${INSTALL_BIN_DIR}") 34 | -------------------------------------------------------------------------------- /src/tools/decompiler.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file tools/decompiler.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief A sample application that uses the library to decompile binary 6 | /// files. 7 | /// 8 | 9 | #include 10 | 11 | #include "retdec/retdec.h" 12 | 13 | using namespace retdec; 14 | 15 | int main(int argc, char **argv) { 16 | if (argc != 3) { 17 | std::cerr << "usage: " << argv[0] << " API-KEY FILE\n"; 18 | return 1; 19 | } 20 | 21 | try { 22 | Decompiler decompiler( 23 | Settings() 24 | .apiKey(argv[1]) 25 | ); 26 | auto decompilation = decompiler.runDecompilation( 27 | DecompilationArguments() 28 | .mode("bin") 29 | .inputFile(File::fromFilesystem(argv[2])) 30 | ); 31 | decompilation->waitUntilFinished(); 32 | std::cout << decompilation->getOutputHll(); 33 | return 0; 34 | } catch (const Error &ex) { 35 | std::cerr << "error: " << ex.what() << "\n"; 36 | return 1; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/tools/fileinfo.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file tools/fileinfo.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief A sample application that uses the library to analyze binary 6 | /// files. 7 | /// 8 | 9 | #include 10 | 11 | #include "retdec/retdec.h" 12 | 13 | using namespace retdec; 14 | 15 | int main(int argc, char **argv) { 16 | if (argc != 3) { 17 | std::cerr << "usage: " << argv[0] << " API-KEY FILE\n"; 18 | return 1; 19 | } 20 | 21 | try { 22 | Fileinfo fileinfo( 23 | Settings() 24 | .apiKey(argv[1]) 25 | ); 26 | auto analysis = fileinfo.runAnalysis( 27 | AnalysisArguments() 28 | .inputFile(File::fromFilesystem(argv[2])) 29 | ); 30 | analysis->waitUntilFinished(); 31 | std::cout << analysis->getOutput(); 32 | return 0; 33 | } catch (const Error &ex) { 34 | std::cerr << "error: " << ex.what() << "\n"; 35 | return 1; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## 2 | ## Project: retdec-cpp 3 | ## Copyright: (c) 2015 by Petr Zemek and contributors 4 | ## License: MIT, see the LICENSE file for more details 5 | ## 6 | ## CMake configuration file for tests. 7 | ## 8 | 9 | if(NOT RETDEC_TESTS) 10 | return() 11 | endif() 12 | 13 | ## 14 | ## Dependencies. 15 | ## 16 | 17 | # Google Test 18 | find_package(GTest) 19 | if(NOT GTEST_FOUND) 20 | message(STATUS " --> GTest will be built as an external project") 21 | ExternalProject_Add(googletest 22 | URL http://googletest.googlecode.com/files/gtest-1.7.0.zip 23 | CMAKE_ARGS 24 | -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} 25 | # Disable the install step. 26 | INSTALL_COMMAND "" 27 | # Wrap the download, configure and build steps in a script to log the 28 | # output. 29 | LOG_DOWNLOAD ON 30 | LOG_CONFIGURE ON 31 | LOG_BUILD ON 32 | ) 33 | ExternalProject_Get_Property(googletest source_dir) 34 | ExternalProject_Get_Property(googletest binary_dir) 35 | set(GTEST_INCLUDE_DIR "${source_dir}/include") 36 | set(GTEST_LIBRARY_DIR "${binary_dir}") 37 | set(GTEST_LIBRARY "gtest") 38 | link_directories(${GTEST_LIBRARY_DIR}) 39 | endif() 40 | include_directories(SYSTEM ${GTEST_INCLUDE_DIR}) 41 | 42 | # Google Mock 43 | find_package(GMock) 44 | if(NOT GMOCK_FOUND) 45 | message(STATUS " --> GMock will be built as an external project") 46 | ExternalProject_Add(googlemock 47 | URL http://googlemock.googlecode.com/files/gmock-1.7.0.zip 48 | # Disable the install step. 49 | CMAKE_ARGS 50 | -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} 51 | INSTALL_COMMAND "" 52 | # Wrap the download, configure and build steps in a script to log the 53 | # output. 54 | LOG_DOWNLOAD ON 55 | LOG_CONFIGURE ON 56 | LOG_BUILD ON 57 | ) 58 | ExternalProject_Get_Property(googlemock source_dir) 59 | ExternalProject_Get_Property(googlemock binary_dir) 60 | set(GMOCK_INCLUDE_DIR "${source_dir}/include") 61 | set(GMOCK_LIBRARY_DIR "${binary_dir}") 62 | set(GMOCK_LIBRARY "gmock") 63 | set(GMOCK_MAIN_LIBRARY "gmock_main") 64 | link_directories(${GMOCK_LIBRARY_DIR}) 65 | endif() 66 | include_directories(SYSTEM ${GMOCK_INCLUDE_DIR}) 67 | 68 | ## 69 | ## Includes. 70 | ## 71 | 72 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 73 | 74 | ## 75 | ## Subdirectories. 76 | ## 77 | 78 | add_subdirectory(retdec) 79 | -------------------------------------------------------------------------------- /tests/retdec/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## 2 | ## Project: retdec-cpp 3 | ## Copyright: (c) 2015 by Petr Zemek and contributors 4 | ## License: MIT, see the LICENSE file for more details 5 | ## 6 | ## CMake configuration file for the tests of the library. 7 | ## 8 | 9 | set(RETDEC_TESTS_SOURCES 10 | analysis_arguments_tests.cpp 11 | analysis_tests.cpp 12 | decompilation_arguments_tests.cpp 13 | decompilation_tests.cpp 14 | decompiler_tests.cpp 15 | exceptions_tests.cpp 16 | file_tests.cpp 17 | fileinfo_tests.cpp 18 | internal/connection_manager_tests.cpp 19 | internal/connection_managers/real_connection_manager_tests.cpp 20 | internal/connection_tests.cpp 21 | internal/connections/real_connection_tests.cpp 22 | internal/files/filesystem_file_tests.cpp 23 | internal/files/string_file_tests.cpp 24 | internal/utilities/connection_tests.cpp 25 | internal/utilities/container_tests.cpp 26 | internal/utilities/json_tests.cpp 27 | internal/utilities/os_tests.cpp 28 | internal/utilities/smart_ptr_tests.cpp 29 | internal/utilities/string_tests.cpp 30 | resource_arguments_tests.cpp 31 | settings_tests.cpp 32 | test_tests.cpp 33 | test_utilities/tmp_file.cpp 34 | ) 35 | 36 | add_executable(retdec_tests ${RETDEC_TESTS_SOURCES}) 37 | if(NOT GTEST_FOUND) 38 | add_dependencies(retdec googletest) 39 | endif() 40 | if(NOT GMOCK_FOUND) 41 | add_dependencies(retdec googlemock) 42 | endif() 43 | target_link_libraries(retdec_tests 44 | retdec 45 | ${GTEST_LIBRARY} 46 | ${GMOCK_LIBRARY} 47 | ${GMOCK_MAIN_LIBRARY} 48 | ) 49 | 50 | install(TARGETS retdec_tests DESTINATION "${INSTALL_BIN_DIR}/tests") 51 | -------------------------------------------------------------------------------- /tests/retdec/analysis_arguments_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/analysis_arguments_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the analysis arguments. 6 | /// 7 | 8 | #include 9 | #include 10 | 11 | #include "retdec/analysis_arguments.h" 12 | #include "retdec/file_mock.h" 13 | 14 | using namespace testing; 15 | 16 | namespace retdec { 17 | namespace tests { 18 | 19 | /// 20 | /// Tests for AnalysisArguments. 21 | /// 22 | class AnalysisArgumentsTests: public Test {}; 23 | 24 | // Verbose. 25 | 26 | TEST_F(AnalysisArgumentsTests, 27 | VerboseYesSetsVerboseToYesInPlace) { 28 | AnalysisArguments args; 29 | 30 | args.verbose("yes"); 31 | 32 | ASSERT_EQ("yes", args.verbose()); 33 | } 34 | 35 | TEST_F(AnalysisArgumentsTests, 36 | VerboseNoSetsVerboseToNoInPlace) { 37 | AnalysisArguments args; 38 | 39 | args.verbose("no"); 40 | 41 | ASSERT_EQ("no", args.verbose()); 42 | } 43 | 44 | TEST_F(AnalysisArgumentsTests, 45 | WithVerboseYesReturnsNewArgumentsWithVerboseSetToYes) { 46 | AnalysisArguments args; 47 | 48 | auto newArgs = args.withVerbose("yes"); 49 | 50 | ASSERT_EQ("yes", newArgs.verbose()); 51 | ASSERT_FALSE(args.hasVerbose()); 52 | } 53 | 54 | TEST_F(AnalysisArgumentsTests, 55 | HasVerboseReturnsFalseByDefault) { 56 | AnalysisArguments args; 57 | 58 | ASSERT_FALSE(args.hasVerbose()); 59 | } 60 | 61 | TEST_F(AnalysisArgumentsTests, 62 | HasVerboseReturnsTrueWhenVerboseIsSetToYes) { 63 | auto args = AnalysisArguments() 64 | .withVerbose("yes"); 65 | 66 | ASSERT_TRUE(args.hasVerbose()); 67 | } 68 | 69 | TEST_F(AnalysisArgumentsTests, 70 | HasVerboseReturnsTrueWhenVerboseIsSetToNo) { 71 | auto args = AnalysisArguments() 72 | .withVerbose("no"); 73 | 74 | ASSERT_TRUE(args.hasVerbose()); 75 | } 76 | 77 | TEST_F(AnalysisArgumentsTests, 78 | HasVerboseReturnsFalseWhenVerboseIsNotSet) { 79 | AnalysisArguments args; 80 | 81 | ASSERT_FALSE(args.hasVerbose()); 82 | } 83 | 84 | // Input file. 85 | 86 | TEST_F(AnalysisArgumentsTests, 87 | InputFileSetsNewInputFileInPlace) { 88 | AnalysisArguments args; 89 | auto file = std::make_shared(); 90 | 91 | args.inputFile(file); 92 | 93 | ASSERT_EQ(file, args.inputFile()); 94 | } 95 | 96 | TEST_F(AnalysisArgumentsTests, 97 | WithInputFileReturnsNewArgumentsWithCorrectInputFile) { 98 | AnalysisArguments args; 99 | auto file = std::make_shared(); 100 | 101 | auto newArgs = args.withInputFile(file); 102 | 103 | ASSERT_EQ(file, newArgs.inputFile()); 104 | } 105 | 106 | TEST_F(AnalysisArgumentsTests, 107 | HasInputFileReturnsTrueWhenInputFileIsSet) { 108 | auto args = AnalysisArguments() 109 | .withInputFile(std::make_shared()); 110 | 111 | ASSERT_TRUE(args.hasInputFile()); 112 | } 113 | 114 | TEST_F(AnalysisArgumentsTests, 115 | HasInputFileReturnsFalseWhenInputFileIsNotSet) { 116 | AnalysisArguments args; 117 | 118 | ASSERT_FALSE(args.hasInputFile()); 119 | } 120 | 121 | // Chaining. 122 | 123 | TEST_F(AnalysisArgumentsTests, 124 | InPlaceSettersAllowChainingForLValue) { 125 | AnalysisArguments args; 126 | auto file = std::make_shared(); 127 | 128 | args.verbose("yes") 129 | .inputFile(file); 130 | 131 | ASSERT_EQ("yes", args.verbose()); 132 | ASSERT_EQ(file, args.inputFile()); 133 | } 134 | 135 | TEST_F(AnalysisArgumentsTests, 136 | InPlaceSettersAllowChainingForRValue) { 137 | auto file = std::make_shared(); 138 | 139 | auto args = AnalysisArguments() 140 | .verbose("yes") 141 | .inputFile(file); 142 | 143 | ASSERT_EQ("yes", args.verbose()); 144 | ASSERT_EQ(file, args.inputFile()); 145 | } 146 | 147 | TEST_F(AnalysisArgumentsTests, 148 | NotModifyingSettersAllowChaining) { 149 | auto file = std::make_shared(); 150 | 151 | auto args = AnalysisArguments() 152 | .verbose("yes") 153 | .withInputFile(file); 154 | 155 | ASSERT_EQ("yes", args.verbose()); 156 | ASSERT_EQ(file, args.inputFile()); 157 | } 158 | 159 | } // namespace tests 160 | } // namespace retdec 161 | -------------------------------------------------------------------------------- /tests/retdec/analysis_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/analysis_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the analysis. 6 | /// 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include "retdec/analysis.h" 14 | #include "retdec/internal/connection_mock.h" 15 | #include "retdec/internal/utilities/json.h" 16 | #include "retdec/settings.h" 17 | 18 | using namespace testing; 19 | using namespace retdec::internal; 20 | using namespace retdec::internal::tests; 21 | 22 | namespace retdec { 23 | namespace tests { 24 | 25 | /// 26 | /// Tests for Analysis. 27 | /// 28 | class AnalysisTests: public Test {}; 29 | 30 | TEST_F(AnalysisTests, 31 | IsCreatedSuccessfully) { 32 | auto conn = std::make_shared>(); 33 | ON_CALL(*conn, getApiUrl()) 34 | .WillByDefault(Return("https://retdec.com/service/api")); 35 | 36 | Analysis analysis("id", conn); 37 | } 38 | 39 | TEST_F(AnalysisTests, 40 | GetIdReturnsCorrectValue) { 41 | auto conn = std::make_shared>(); 42 | ON_CALL(*conn, getApiUrl()) 43 | .WillByDefault(Return("https://retdec.com/service/api")); 44 | 45 | Analysis analysis("123", conn); 46 | 47 | ASSERT_EQ("123", analysis.getId()); 48 | } 49 | 50 | TEST_F(AnalysisTests, 51 | HasFinishedSendsCorrectRequestWhenNoFinishedInfo) { 52 | auto refResponse = std::make_unique>(); 53 | ON_CALL(*refResponse, statusCode()) 54 | .WillByDefault(Return(200)); // HTTP 200 OK 55 | ON_CALL(*refResponse, bodyAsJson()) 56 | .WillByDefault(Return(toJson("{\"finished\": false}"))); 57 | 58 | auto conn = std::make_shared>(); 59 | ON_CALL(*conn, getApiUrl()) 60 | .WillByDefault(Return("https://retdec.com/service/api")); 61 | EXPECT_CALL(*conn, sendGetRequestProxy( 62 | "https://retdec.com/service/api/fileinfo/analyses/123/status")) 63 | .WillOnce(Return(refResponse.release())); 64 | 65 | Analysis analysis("123", conn); 66 | analysis.hasFinished(); 67 | } 68 | 69 | } // namespace tests 70 | } // namespace retdec 71 | -------------------------------------------------------------------------------- /tests/retdec/decompilation_arguments_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/decompilation_arguments_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the decompilation arguments. 6 | /// 7 | 8 | #include 9 | #include 10 | 11 | #include "retdec/decompilation_arguments.h" 12 | #include "retdec/file_mock.h" 13 | 14 | using namespace testing; 15 | 16 | namespace retdec { 17 | namespace tests { 18 | 19 | /// 20 | /// Tests for DecompilationArguments. 21 | /// 22 | class DecompilationArgumentsTests: public Test {}; 23 | 24 | // Mode. 25 | 26 | TEST_F(DecompilationArgumentsTests, 27 | ModeSetsNewModeInPlace) { 28 | DecompilationArguments args; 29 | 30 | args.mode("c"); 31 | 32 | ASSERT_EQ("c", args.mode()); 33 | } 34 | 35 | TEST_F(DecompilationArgumentsTests, 36 | WithModeReturnsNewArgumentsWithCorrectMode) { 37 | DecompilationArguments args; 38 | 39 | auto newArgs = args.withMode("c"); 40 | 41 | ASSERT_EQ("c", newArgs.mode()); 42 | } 43 | 44 | TEST_F(DecompilationArgumentsTests, 45 | HasModeReturnsTrueWhenModeIsSet) { 46 | auto args = DecompilationArguments() 47 | .withMode("c"); 48 | 49 | ASSERT_TRUE(args.hasMode()); 50 | } 51 | 52 | TEST_F(DecompilationArgumentsTests, 53 | HasModeReturnsFalseWhenModeIsNotSet) { 54 | DecompilationArguments args; 55 | 56 | ASSERT_FALSE(args.hasMode()); 57 | } 58 | 59 | // Selective decompilation: ranges. 60 | 61 | TEST_F(DecompilationArgumentsTests, 62 | SelDecompRangesSetsNewRangesInPlace) { 63 | DecompilationArguments args; 64 | 65 | args.selDecompRanges("0x0-0x1"); 66 | 67 | ASSERT_EQ("0x0-0x1", args.selDecompRanges()); 68 | } 69 | 70 | TEST_F(DecompilationArgumentsTests, 71 | WithSelDecompRangesReturnsNewArgumentsWithCorrectRanges) { 72 | DecompilationArguments args; 73 | 74 | auto newArgs = args.withSelDecompRanges("0x0-0x1"); 75 | 76 | ASSERT_EQ("0x0-0x1", newArgs.selDecompRanges()); 77 | } 78 | 79 | TEST_F(DecompilationArgumentsTests, 80 | HasSelDecompRangesReturnsTrueWhenSelDecompRangesIsSet) { 81 | auto args = DecompilationArguments() 82 | .withSelDecompRanges("0x0-0x1"); 83 | 84 | ASSERT_TRUE(args.hasSelDecompRanges()); 85 | } 86 | 87 | TEST_F(DecompilationArgumentsTests, 88 | HasSelDecompRangesReturnsFalseWhenSelDecompRangesIsNotSet) { 89 | DecompilationArguments args; 90 | 91 | ASSERT_FALSE(args.hasSelDecompRanges()); 92 | } 93 | 94 | // Selective decompilation: decoding. 95 | 96 | TEST_F(DecompilationArgumentsTests, 97 | SelDecompDecodingSetsNewDecodingInPlace) { 98 | DecompilationArguments args; 99 | 100 | args.selDecompDecoding("only"); 101 | 102 | ASSERT_EQ("only", args.selDecompDecoding()); 103 | } 104 | 105 | TEST_F(DecompilationArgumentsTests, 106 | WithSelDecompDecodingReturnsNewArgumentsWithCorrectDecoding) { 107 | DecompilationArguments args; 108 | 109 | auto newArgs = args.withSelDecompDecoding("only"); 110 | 111 | ASSERT_EQ("only", newArgs.selDecompDecoding()); 112 | } 113 | 114 | TEST_F(DecompilationArgumentsTests, 115 | HasSelDecompDecodingReturnsTrueWhenSelDecompDecodingIsSet) { 116 | auto args = DecompilationArguments() 117 | .withSelDecompDecoding("only"); 118 | 119 | ASSERT_TRUE(args.hasSelDecompDecoding()); 120 | } 121 | 122 | TEST_F(DecompilationArgumentsTests, 123 | HasSelDecompDecodingReturnsFalseWhenSelDecompDecodingIsNotSet) { 124 | DecompilationArguments args; 125 | 126 | ASSERT_FALSE(args.hasSelDecompDecoding()); 127 | } 128 | 129 | // Files: input. 130 | 131 | TEST_F(DecompilationArgumentsTests, 132 | InputFileSetsNewInputFileInPlace) { 133 | DecompilationArguments args; 134 | auto file = std::make_shared(); 135 | 136 | args.inputFile(file); 137 | 138 | ASSERT_EQ(file, args.inputFile()); 139 | } 140 | 141 | TEST_F(DecompilationArgumentsTests, 142 | WithInputFileReturnsNewArgumentsWithCorrectInputFile) { 143 | DecompilationArguments args; 144 | auto file = std::make_shared(); 145 | 146 | auto newArgs = args.withInputFile(file); 147 | 148 | ASSERT_EQ(file, newArgs.inputFile()); 149 | } 150 | 151 | TEST_F(DecompilationArgumentsTests, 152 | HasInputFileReturnsTrueWhenInputFileIsSet) { 153 | auto args = DecompilationArguments() 154 | .withInputFile(std::make_shared()); 155 | 156 | ASSERT_TRUE(args.hasInputFile()); 157 | } 158 | 159 | TEST_F(DecompilationArgumentsTests, 160 | HasInputFileReturnsFalseWhenInputFileIsNotSet) { 161 | DecompilationArguments args; 162 | 163 | ASSERT_FALSE(args.hasInputFile()); 164 | } 165 | 166 | // Chaining. 167 | 168 | TEST_F(DecompilationArgumentsTests, 169 | InPlaceSettersAllowChainingForLValue) { 170 | DecompilationArguments args; 171 | auto file = std::make_shared(); 172 | 173 | args.mode("c") 174 | .inputFile(file); 175 | 176 | ASSERT_EQ("c", args.mode()); 177 | ASSERT_EQ(file, args.inputFile()); 178 | } 179 | 180 | TEST_F(DecompilationArgumentsTests, 181 | InPlaceSettersAllowChainingForRValue) { 182 | auto file = std::make_shared(); 183 | 184 | auto args = DecompilationArguments() 185 | .mode("c") 186 | .inputFile(file); 187 | 188 | ASSERT_EQ("c", args.mode()); 189 | ASSERT_EQ(file, args.inputFile()); 190 | } 191 | 192 | TEST_F(DecompilationArgumentsTests, 193 | NotModifyingSettersAllowChaining) { 194 | auto file = std::make_shared(); 195 | 196 | auto args = DecompilationArguments() 197 | .withMode("c") 198 | .withInputFile(file); 199 | 200 | ASSERT_EQ("c", args.mode()); 201 | ASSERT_EQ(file, args.inputFile()); 202 | } 203 | 204 | } // namespace tests 205 | } // namespace retdec 206 | -------------------------------------------------------------------------------- /tests/retdec/decompilation_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/decompilation_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the decompilation. 6 | /// 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include "retdec/decompilation.h" 14 | #include "retdec/internal/connection_mock.h" 15 | #include "retdec/internal/utilities/json.h" 16 | #include "retdec/settings.h" 17 | 18 | using namespace testing; 19 | using namespace retdec::internal; 20 | using namespace retdec::internal::tests; 21 | 22 | namespace retdec { 23 | namespace tests { 24 | 25 | /// 26 | /// Tests for Decompilation. 27 | /// 28 | class DecompilationTests: public Test {}; 29 | 30 | TEST_F(DecompilationTests, 31 | IsCreatedSuccessfully) { 32 | auto conn = std::make_shared>(); 33 | ON_CALL(*conn, getApiUrl()) 34 | .WillByDefault(Return("https://retdec.com/service/api")); 35 | 36 | Decompilation decompilation("id", conn); 37 | } 38 | 39 | TEST_F(DecompilationTests, 40 | GetIdReturnsCorrectValue) { 41 | auto conn = std::make_shared>(); 42 | ON_CALL(*conn, getApiUrl()) 43 | .WillByDefault(Return("https://retdec.com/service/api")); 44 | 45 | Decompilation decompilation("123", conn); 46 | 47 | ASSERT_EQ("123", decompilation.getId()); 48 | } 49 | 50 | TEST_F(DecompilationTests, 51 | HasFinishedSendsCorrectRequestWhenNoFinishedInfo) { 52 | auto refResponse = std::make_unique>(); 53 | ON_CALL(*refResponse, statusCode()) 54 | .WillByDefault(Return(200)); // HTTP 200 OK 55 | ON_CALL(*refResponse, bodyAsJson()) 56 | .WillByDefault(Return(toJson("{\"finished\": false}"))); 57 | 58 | auto conn = std::make_shared>(); 59 | ON_CALL(*conn, getApiUrl()) 60 | .WillByDefault(Return("https://retdec.com/service/api")); 61 | EXPECT_CALL(*conn, sendGetRequestProxy( 62 | "https://retdec.com/service/api/decompiler/decompilations/123/status")) 63 | .WillOnce(Return(refResponse.release())); 64 | 65 | Decompilation decompilation("123", conn); 66 | decompilation.hasFinished(); 67 | } 68 | 69 | } // namespace tests 70 | } // namespace retdec 71 | -------------------------------------------------------------------------------- /tests/retdec/decompiler_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/decompiler_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the decompilation service. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/decompiler.h" 11 | #include "retdec/internal/connection_manager_mock.h" 12 | #include "retdec/settings.h" 13 | 14 | using namespace testing; 15 | using namespace retdec::internal; 16 | using namespace retdec::internal::tests; 17 | 18 | namespace retdec { 19 | namespace tests { 20 | 21 | /// 22 | /// Tests for Decompiler. 23 | /// 24 | class DecompilerTests: public Test {}; 25 | 26 | TEST_F(DecompilerTests, 27 | IsCreatedSuccessfullyWithDefaultConnectionManager) { 28 | Decompiler decompiler{ 29 | Settings() 30 | }; 31 | } 32 | 33 | TEST_F(DecompilerTests, 34 | IsCreatedSuccessfullyWithCustomConnectionManager) { 35 | auto connectionManager = std::make_shared(); 36 | Decompiler decompiler( 37 | Settings(), 38 | connectionManager 39 | ); 40 | } 41 | 42 | } // namespace tests 43 | } // namespace retdec 44 | -------------------------------------------------------------------------------- /tests/retdec/exceptions_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/exceptions_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the exceptions. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/exceptions.h" 11 | 12 | using namespace testing; 13 | 14 | namespace retdec { 15 | namespace tests { 16 | 17 | /// 18 | /// Tests for Error. 19 | /// 20 | class ErrorTests: public Test {}; 21 | 22 | TEST_F(ErrorTests, 23 | WhatReturnsCorrectMessage) { 24 | const std::string RefErrorMessage("error message"); 25 | 26 | Error ex(RefErrorMessage); 27 | 28 | ASSERT_EQ(RefErrorMessage, ex.what()); 29 | } 30 | 31 | /// 32 | /// Tests for IoError. 33 | /// 34 | class IoErrorTests: public Test {}; 35 | 36 | TEST_F(IoErrorTests, 37 | WhatReturnsCorrectMessage) { 38 | const std::string RefIoErrorMessage("error message"); 39 | 40 | IoError ex(RefIoErrorMessage); 41 | 42 | ASSERT_EQ(RefIoErrorMessage, ex.what()); 43 | } 44 | 45 | /// 46 | /// Tests for FilesystemError. 47 | /// 48 | class FilesystemErrorTests: public Test {}; 49 | 50 | TEST_F(FilesystemErrorTests, 51 | WhatReturnsCorrectMessage) { 52 | const std::string RefFilesystemErrorMessage("error message"); 53 | 54 | FilesystemError ex(RefFilesystemErrorMessage); 55 | 56 | ASSERT_EQ(RefFilesystemErrorMessage, ex.what()); 57 | } 58 | 59 | /// 60 | /// Tests for ConnectionError. 61 | /// 62 | class ConnectionErrorTests: public Test {}; 63 | 64 | TEST_F(ConnectionErrorTests, 65 | WhatReturnsCorrectMessage) { 66 | const std::string RefConnectionErrorMessage("error message"); 67 | 68 | ConnectionError ex(RefConnectionErrorMessage); 69 | 70 | ASSERT_EQ(RefConnectionErrorMessage, ex.what()); 71 | } 72 | 73 | /// 74 | /// Tests for ApiError. 75 | /// 76 | class ApiErrorTests: public Test {}; 77 | 78 | TEST_F(ApiErrorTests, 79 | GettersAndWhatReturnCorrectValuesWhenDescriptionIsGiven) { 80 | ApiError ex(404, "Not Found", "The page was not found."); 81 | 82 | ASSERT_STREQ("404 Not Found", ex.what()); 83 | ASSERT_EQ(404, ex.getCode()); 84 | ASSERT_EQ("Not Found", ex.getMessage()); 85 | ASSERT_EQ("The page was not found.", ex.getDescription()); 86 | } 87 | 88 | TEST_F(ApiErrorTests, 89 | GetDescriptionReturnsSameValueAsWhatWhenDescriptionIsNotGiven) { 90 | ApiError e(404, "Not Found"); 91 | 92 | ASSERT_EQ(e.what(), e.getDescription()); 93 | } 94 | 95 | /// 96 | /// Tests for AuthError. 97 | /// 98 | class AuthErrorTests: public Test {}; 99 | 100 | TEST_F(AuthErrorTests, 101 | GettersAndWhatReturnCorrectValuesWhenDescriptionIsGiven) { 102 | AuthError ex(401, "Unauthorized by API Key", "API key authorization failed."); 103 | 104 | ASSERT_STREQ("401 Unauthorized by API Key", ex.what()); 105 | ASSERT_EQ(401, ex.getCode()); 106 | ASSERT_EQ("Unauthorized by API Key", ex.getMessage()); 107 | ASSERT_EQ("API key authorization failed.", ex.getDescription()); 108 | } 109 | 110 | TEST_F(AuthErrorTests, 111 | GetDescriptionReturnsSameValueAsWhatWhenDescriptionIsNotGiven) { 112 | AuthError e(401, "Unauthorized by API Key"); 113 | 114 | ASSERT_EQ(e.what(), e.getDescription()); 115 | } 116 | 117 | /// 118 | /// Tests for DecompilationError. 119 | /// 120 | class DecompilationErrorTests: public Test {}; 121 | 122 | TEST_F(DecompilationErrorTests, 123 | WhatReturnsCorrectMessage) { 124 | const std::string RefDecompilationErrorMessage("error message"); 125 | 126 | DecompilationError ex(RefDecompilationErrorMessage); 127 | 128 | ASSERT_EQ(RefDecompilationErrorMessage, ex.what()); 129 | } 130 | 131 | /// 132 | /// Tests for AnalysisError. 133 | /// 134 | class AnalysisErrorTests: public Test {}; 135 | 136 | TEST_F(AnalysisErrorTests, 137 | WhatReturnsCorrectMessage) { 138 | const std::string RefAnalysisErrorMessage("error message"); 139 | 140 | AnalysisError ex(RefAnalysisErrorMessage); 141 | 142 | ASSERT_EQ(RefAnalysisErrorMessage, ex.what()); 143 | } 144 | 145 | } // namespace tests 146 | } // namespace retdec 147 | -------------------------------------------------------------------------------- /tests/retdec/file_mock.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/file_mock.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Mock for File. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_FILE_MOCK_H 9 | #define RETDEC_INTERNAL_FILE_MOCK_H 10 | 11 | #include 12 | 13 | #include "retdec/file.h" 14 | 15 | namespace retdec { 16 | namespace tests { 17 | 18 | /// 19 | /// Mock for File. 20 | /// 21 | class FileMock: public File { 22 | MOCK_CONST_METHOD0(getName, std::string ()); 23 | MOCK_METHOD0(getContent, std::string ()); 24 | MOCK_METHOD1(saveCopyTo, void (const std::string &)); 25 | MOCK_METHOD2(saveCopyTo, void (const std::string &, const std::string &)); 26 | }; 27 | 28 | } // namespace tests 29 | } // namespace retdec 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /tests/retdec/file_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/file_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the files. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/file.h" 11 | #include "retdec/internal/utilities/os.h" 12 | 13 | using namespace testing; 14 | 15 | namespace retdec { 16 | namespace tests { 17 | 18 | /// 19 | /// Tests for File. 20 | /// 21 | class FileTests: public Test {}; 22 | 23 | TEST_F(FileTests, 24 | FromContentWithNameReturnsFileWithCorrectContentAndName) { 25 | auto file = File::fromContentWithName("content", "file.txt"); 26 | 27 | ASSERT_EQ("content", file->getContent()); 28 | ASSERT_EQ("file.txt", file->getName()); 29 | } 30 | 31 | TEST_F(FileTests, 32 | FromFilesystemReturnsFileWithCorrectName) { 33 | #ifdef RETDEC_OS_WINDOWS 34 | auto file = File::fromFilesystem(R"(C:\\/path/to/file.txt)") 35 | #else 36 | auto file = File::fromFilesystem("/path/to/file.txt"); 37 | #endif 38 | 39 | ASSERT_EQ("file.txt", file->getName()); 40 | } 41 | 42 | TEST_F(FileTests, 43 | FromFilesystemWithOtherNameReturnsFileWithCorrectName) { 44 | #ifdef RETDEC_OS_WINDOWS 45 | auto file = File::fromFilesystemWithOtherName( 46 | R"(C:\\/path/to/file.txt)", "other.txt") 47 | #else 48 | auto file = File::fromFilesystemWithOtherName( 49 | "/path/to/file.txt", "other.txt"); 50 | #endif 51 | 52 | ASSERT_EQ("other.txt", file->getName()); 53 | } 54 | 55 | } // namespace tests 56 | } // namespace retdec 57 | -------------------------------------------------------------------------------- /tests/retdec/fileinfo_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/fileinfo_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the fileinfo service. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/fileinfo.h" 11 | #include "retdec/internal/connection_manager_mock.h" 12 | #include "retdec/settings.h" 13 | 14 | using namespace testing; 15 | using namespace retdec::internal; 16 | using namespace retdec::internal::tests; 17 | 18 | namespace retdec { 19 | namespace tests { 20 | 21 | /// 22 | /// Tests for Fileinfo. 23 | /// 24 | class FileinfoTests: public Test {}; 25 | 26 | TEST_F(FileinfoTests, 27 | IsCreatedSuccessfullyWithDefaultConnectionManager) { 28 | Fileinfo fileinfo{ 29 | Settings() 30 | }; 31 | } 32 | 33 | TEST_F(FileinfoTests, 34 | IsCreatedSuccessfullyWithCustomConnectionManager) { 35 | auto connectionManager = std::make_shared(); 36 | Fileinfo fileinfo( 37 | Settings(), 38 | connectionManager 39 | ); 40 | } 41 | 42 | } // namespace tests 43 | } // namespace retdec 44 | -------------------------------------------------------------------------------- /tests/retdec/internal/connection_manager_mock.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connection_manager_mock.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Mock for ConnectionManager. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_CONNECTION_MANAGER_MOCK_H 9 | #define RETDEC_INTERNAL_CONNECTION_MANAGER_MOCK_H 10 | 11 | #include 12 | 13 | #include "retdec/internal/connection_manager.h" 14 | 15 | namespace retdec { 16 | namespace internal { 17 | namespace tests { 18 | 19 | /// 20 | /// Mock for ConnectionManager. 21 | /// 22 | class ConnectionManagerMock: public ConnectionManager { 23 | public: 24 | ConnectionManagerMock() = default; 25 | virtual ~ConnectionManagerMock() override = default; 26 | 27 | MOCK_METHOD1(newConnection, std::shared_ptr (const Settings &settings)); 28 | }; 29 | 30 | } // namespace tests 31 | } // namespace internal 32 | } // namespace retdec 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /tests/retdec/internal/connection_manager_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connection_manager_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the base class of connection managers. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/connection_manager.h" 11 | 12 | using namespace testing; 13 | 14 | namespace retdec { 15 | namespace internal { 16 | namespace tests { 17 | 18 | /// 19 | /// Tests for ConnectionManager. 20 | /// 21 | class ConnectionManagerTests: public Test {}; 22 | 23 | } // namespace tests 24 | } // namespace internal 25 | } // namespace retdec 26 | -------------------------------------------------------------------------------- /tests/retdec/internal/connection_managers/real_connection_manager_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connection_managers/real_connection_manager_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the manager of the connections to the API. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/connection_managers/real_connection_manager.h" 11 | #include "retdec/internal/connections/real_connection.h" 12 | #include "retdec/internal/utilities/smart_ptr.h" 13 | #include "retdec/settings.h" 14 | 15 | using namespace testing; 16 | 17 | namespace retdec { 18 | namespace internal { 19 | namespace tests { 20 | 21 | /// 22 | /// Tests for RealConnectionManager. 23 | /// 24 | class RealConnectionManagerTests: public Test {}; 25 | 26 | TEST_F(RealConnectionManagerTests, 27 | NewConnectionReturnsRealConnection) { 28 | RealConnectionManager cm; 29 | 30 | auto conn = cm.newConnection(Settings()); 31 | 32 | ASSERT_TRUE(isa(conn)); 33 | } 34 | 35 | } // namespace tests 36 | } // namespace internal 37 | } // namespace retdec 38 | -------------------------------------------------------------------------------- /tests/retdec/internal/connection_mock.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connection_mock.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Mock for Connection. 6 | /// 7 | 8 | #ifndef RETDEC_INTERNAL_CONNECTION_MOCK_H 9 | #define RETDEC_INTERNAL_CONNECTION_MOCK_H 10 | 11 | #include 12 | 13 | #include "retdec/file.h" 14 | #include "retdec/internal/connection.h" 15 | 16 | namespace retdec { 17 | namespace internal { 18 | namespace tests { 19 | 20 | /// 21 | /// Mock for Connection::Response. 22 | /// 23 | class ResponseMock: public Connection::Response { 24 | public: 25 | ResponseMock() = default; 26 | virtual ~ResponseMock() override = default; 27 | 28 | MOCK_CONST_METHOD0(statusCode, int()); 29 | MOCK_CONST_METHOD0(statusMessage, std::string ()); 30 | MOCK_CONST_METHOD0(body, std::string ()); 31 | MOCK_CONST_METHOD0(bodyAsJson, Json::Value ()); 32 | 33 | // A workaround is needed due to the lack of support of non-copyable return 34 | // types/parameters in Google Mock. 35 | // http://stackoverflow.com/a/11548191/2580955 36 | virtual std::unique_ptr bodyAsFile() const override { 37 | return std::unique_ptr(bodyAsFileProxy()); 38 | } 39 | MOCK_CONST_METHOD0(bodyAsFileProxy, File * ()); 40 | }; 41 | 42 | /// 43 | /// Mock for Connection. 44 | /// 45 | class ConnectionMock: public Connection { 46 | public: 47 | ConnectionMock() = default; 48 | virtual ~ConnectionMock() override = default; 49 | 50 | MOCK_CONST_METHOD0(getApiUrl, Url()); 51 | 52 | // Workarounds are needed due to the lack of support of non-copyable return 53 | // types/parameters in Google Mock. 54 | // http://stackoverflow.com/a/11548191/2580955 55 | 56 | virtual std::unique_ptr sendGetRequest(const Url &url) override { 57 | return std::unique_ptr(sendGetRequestProxy(url)); 58 | } 59 | MOCK_METHOD1(sendGetRequestProxy, Response * (const Url &)); 60 | 61 | virtual std::unique_ptr sendGetRequest(const Url &url, 62 | const RequestArguments &args) override { 63 | return std::unique_ptr(sendGetRequestProxy(url, args)); 64 | } 65 | MOCK_METHOD2(sendGetRequestProxy, Response * (const Url &, 66 | const RequestArguments &)); 67 | 68 | virtual std::unique_ptr sendPostRequest(const Url &url, 69 | const RequestArguments &args, 70 | const RequestFiles &files) override { 71 | return std::unique_ptr(sendPostRequestProxy(url, args, files)); 72 | } 73 | MOCK_METHOD3(sendPostRequestProxy, Response * (const Url &, 74 | const RequestArguments &, const RequestFiles &)); 75 | }; 76 | 77 | } // namespace tests 78 | } // namespace internal 79 | } // namespace retdec 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /tests/retdec/internal/connection_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connection_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the connection to the API. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/connection.h" 11 | 12 | using namespace testing; 13 | 14 | namespace retdec { 15 | namespace internal { 16 | namespace tests { 17 | 18 | /// 19 | /// Tests for Connection. 20 | /// 21 | class ConnectionTests: public Test {}; 22 | 23 | } // namespace tests 24 | } // namespace internal 25 | } // namespace retdec 26 | -------------------------------------------------------------------------------- /tests/retdec/internal/connections/real_connection_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/connections/real_connection_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the real connection to the API. 6 | /// 7 | 8 | // Currently, the tests for RealConnection can run only on Linux. 9 | #include "retdec/internal/utilities/os.h" 10 | #ifndef RETDEC_OS_WINDOWS 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | 21 | #include "retdec/internal/connections/real_connection.h" 22 | #include "retdec/settings.h" 23 | 24 | /// 25 | /// Asserts that @a response contains @a text. 26 | /// 27 | #define ASSERT_CONTAINS(response, text) \ 28 | ASSERT_TRUE(contains(response.get(), text)) << response->body(); 29 | 30 | using namespace testing; 31 | 32 | namespace retdec { 33 | namespace internal { 34 | namespace tests { 35 | 36 | /// 37 | /// Tests for RealConnection. 38 | /// 39 | class RealConnectionTests: public Test { 40 | public: 41 | virtual void SetUp() override; 42 | virtual void TearDown() override; 43 | 44 | struct HttpServerHandler; 45 | 46 | /// Type of the used HTTP server. 47 | using HttpServer = boost::network::http::server; 48 | 49 | /// Handler for the HTTP server. 50 | struct HttpServerHandler { 51 | void operator()(const HttpServer::request &request, 52 | HttpServer::response &response); 53 | void log(const std::string &error); 54 | }; 55 | 56 | void startHttpServer(); 57 | void stopHttpServer(); 58 | bool contains(const Connection::Response *response, 59 | const std::string &text); 60 | 61 | /// PID of the HTTP server. 62 | pid_t httpServerPid = -1; 63 | 64 | /// Host on which the HTTP server runs. 65 | static const std::string HttpServerHost; 66 | 67 | /// Port on which the HTTP server runs. 68 | static const std::string HttpServerPort; 69 | 70 | /// HTTP URL of the server. 71 | static const std::string HttpServerUrl; 72 | }; 73 | 74 | // Static variable definitions. 75 | const std::string RealConnectionTests::HttpServerHost = "127.0.0.1"; 76 | const std::string RealConnectionTests::HttpServerPort = "8000"; 77 | const std::string RealConnectionTests::HttpServerUrl = "http://" + 78 | HttpServerHost + ":" + HttpServerPort; 79 | 80 | /// 81 | /// Handles the given request. 82 | /// 83 | void RealConnectionTests::HttpServerHandler::operator()( 84 | const HttpServer::request &request, HttpServer::response &response) { 85 | // Put the request data into the response's body. In this way, we can later 86 | // check that a proper request was sent. 87 | // 88 | // Example: 89 | // 90 | // GET /api HTTP/1.1 91 | // Authorization: Basic LTo= 92 | // Host: 127.0.0.1:8000 93 | // Accept: */* 94 | // Accept-Encoding: identity;q=1.0, *;q=0 95 | // 96 | // $REQUEST_BODY 97 | // 98 | std::ostringstream body; 99 | body << request.method << " " << request.destination << " HTTP/" << 100 | static_cast(request.http_version_major) << "." << 101 | static_cast(request.http_version_minor) << "\r\n"; 102 | for (auto &header : request.headers) { 103 | body << header.name << ": " << header.value << "\r\n"; 104 | } 105 | body << "\r\n"; 106 | body << request.body; 107 | response = HttpServer::response::stock_reply( 108 | HttpServer::response::ok, body.str()); 109 | } 110 | 111 | /// 112 | /// Logs the given error. 113 | /// 114 | void RealConnectionTests::HttpServerHandler::log(const std::string &error) { 115 | // Ignore errors as there is not much we can do. 116 | static_cast(error); 117 | } 118 | 119 | // Override. 120 | void RealConnectionTests::SetUp() { 121 | startHttpServer(); 122 | } 123 | 124 | // Override. 125 | void RealConnectionTests::TearDown() { 126 | stopHttpServer(); 127 | } 128 | 129 | /// 130 | /// Checks if @a response contains the given text. 131 | /// 132 | bool RealConnectionTests::contains(const Connection::Response *response, 133 | const std::string &text) { 134 | return response->body().find(text) != std::string::npos; 135 | } 136 | 137 | /// 138 | /// Starts the HTTP server (asynchronously). 139 | /// 140 | void RealConnectionTests::startHttpServer() { 141 | // To run the server asynchronously, we run it in a separate process. I was 142 | // unable to use threads (boost::thread) to run the server since running 143 | // both the client and server in the same process failed to execute 144 | // properly (it segfaulted). To this end, we use processes, which work OK. 145 | // Alas, this solution is not portable so it requires a different 146 | // implementation for Linux and MS Windows. 147 | auto pid = fork(); 148 | if (pid == 0) { 149 | // Child process. 150 | HttpServerHandler handler; 151 | HttpServer server( 152 | HttpServer::options(handler) 153 | .address(HttpServerHost) 154 | .port(HttpServerPort) 155 | .reuse_address(true) 156 | ); 157 | // Enter an infinite event-processing loop. 158 | server.run(); 159 | std::exit(0); 160 | } else { 161 | // Parent process. 162 | httpServerPid = pid; 163 | 164 | // Wait to make sure that the server has started. 165 | sleep(100); 166 | } 167 | } 168 | 169 | /// 170 | /// Stops the HTTP server. 171 | /// 172 | void RealConnectionTests::stopHttpServer() { 173 | kill(httpServerPid, SIGTERM); 174 | waitpid(httpServerPid, nullptr, 0); 175 | } 176 | 177 | TEST_F(RealConnectionTests, 178 | ApiUrlReturnsCorrectUrl) { 179 | RealConnection conn(Settings().withApiUrl("http://127.0.0.1:5000/api")); 180 | 181 | ASSERT_EQ("http://127.0.0.1:5000/api", conn.getApiUrl()); 182 | } 183 | 184 | TEST_F(RealConnectionTests, 185 | GetWithoutArgumentsSendsRequestWithCorrectMethodAndDestinationAndHttpVersion) { 186 | const auto ApiUrl = HttpServerUrl + "/api"; 187 | RealConnection conn(Settings().withApiUrl(ApiUrl)); 188 | 189 | auto response = conn.sendGetRequest(ApiUrl + "/test"); 190 | 191 | ASSERT_CONTAINS(response, "GET /api/test HTTP/1.1"); 192 | } 193 | 194 | TEST_F(RealConnectionTests, 195 | GetSendsRequestWithUserAgentHeader) { 196 | const auto ApiUrl = HttpServerUrl + "/api"; 197 | RealConnection conn( 198 | Settings() 199 | .withApiUrl(ApiUrl) 200 | .withUserAgent("my user agent") 201 | ); 202 | 203 | auto response = conn.sendGetRequest(ApiUrl); 204 | 205 | ASSERT_CONTAINS(response, "User-Agent: my user agent"); 206 | } 207 | 208 | } // namespace tests 209 | } // namespace internal 210 | } // namespace retdec 211 | 212 | #endif 213 | -------------------------------------------------------------------------------- /tests/retdec/internal/files/filesystem_file_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/files/filesystem_file_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the file stored in a filesystem. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/files/filesystem_file.h" 11 | #include "retdec/internal/utilities/os.h" 12 | #include "retdec/test_utilities/tmp_file.h" 13 | 14 | using namespace testing; 15 | using namespace retdec::tests; 16 | 17 | namespace retdec { 18 | namespace internal { 19 | namespace tests { 20 | 21 | /// 22 | /// Tests for FilesystemFile. 23 | /// 24 | class FilesystemFileTests: public Test {}; 25 | 26 | TEST_F(FilesystemFileTests, 27 | GetNameReturnsCorrectValueWhenNoCustomNameIsGiven) { 28 | #ifdef RETDEC_OS_WINDOWS 29 | FilesystemFile file(R"(C:\\/path/to/file.txt)"); 30 | #else 31 | FilesystemFile file("/path/to/file.txt"); 32 | #endif 33 | 34 | ASSERT_EQ("file.txt", file.getName()); 35 | } 36 | 37 | TEST_F(FilesystemFileTests, 38 | GetNameReturnsCorrectValueWhenCustomNameIsGiven) { 39 | FilesystemFile file("/path/to/file.txt", "another_file.txt"); 40 | 41 | ASSERT_EQ("another_file.txt", file.getName()); 42 | } 43 | 44 | TEST_F(FilesystemFileTests, 45 | GetContentReturnsCorrectContent) { 46 | auto tmpFile = TmpFile::createWithContent("content"); 47 | FilesystemFile file(tmpFile->getPath()); 48 | 49 | ASSERT_EQ("content", file.getContent()); 50 | } 51 | 52 | TEST_F(FilesystemFileTests, 53 | SaveCopyToSavesCopyOfFileToGivenDirectory) { 54 | const std::string Content("content"); 55 | auto tmpFile = TmpFile::createWithContent(Content); 56 | const std::string Name("retdec-cpp-filesystem-file-save-copy-to-test.txt"); 57 | FilesystemFile file(tmpFile->getPath(), Name); 58 | 59 | file.saveCopyTo("."); 60 | 61 | RemoveFileOnDestruction remover(Name); 62 | ASSERT_EQ(Content, readFile(Name)); 63 | } 64 | 65 | } // namespace tests 66 | } // namespace internal 67 | } // namespace retdec 68 | -------------------------------------------------------------------------------- /tests/retdec/internal/files/string_file_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/files/string_file_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the file storing its content in a string. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/files/string_file.h" 11 | #include "retdec/internal/utilities/os.h" 12 | #include "retdec/test_utilities/tmp_file.h" 13 | 14 | using namespace testing; 15 | using namespace retdec::tests; 16 | 17 | namespace retdec { 18 | namespace internal { 19 | namespace tests { 20 | 21 | /// 22 | /// Tests for StringFile. 23 | /// 24 | class StringFileTests: public Test {}; 25 | 26 | TEST_F(StringFileTests, 27 | FileHasCorrectContentUponCreation) { 28 | StringFile file("content"); 29 | 30 | ASSERT_EQ("content", file.getContent()); 31 | } 32 | 33 | TEST_F(StringFileTests, 34 | GetNameReturnsCorrectNameWhenFileHasName) { 35 | StringFile file("content", "file.txt"); 36 | 37 | ASSERT_EQ("file.txt", file.getName()); 38 | } 39 | 40 | TEST_F(StringFileTests, 41 | GetNameReturnsEmptyStringWhenFileHasNoName) { 42 | StringFile file("content"); 43 | 44 | ASSERT_EQ("", file.getName()); 45 | } 46 | 47 | TEST_F(StringFileTests, 48 | SaveCopyToSavesCopyOfFileToGivenDirectory) { 49 | const std::string Content("content"); 50 | const std::string Name("retdec-cpp-string-file-save-copy-to-test.txt"); 51 | StringFile file{Content, Name}; 52 | 53 | file.saveCopyTo("."); 54 | 55 | RemoveFileOnDestruction remover(Name); 56 | ASSERT_EQ(Content, readFile(Name)); 57 | } 58 | 59 | } // namespace tests 60 | } // namespace internal 61 | } // namespace retdec 62 | -------------------------------------------------------------------------------- /tests/retdec/internal/utilities/container_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/containertests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for container utilities. 6 | /// 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include "retdec/internal/utilities/container.h" 13 | 14 | using namespace testing; 15 | 16 | namespace retdec { 17 | namespace internal { 18 | namespace tests { 19 | 20 | /// 21 | /// Tests for hasKey(). 22 | /// 23 | class HasKeyTests: public Test {}; 24 | 25 | TEST_F(HasKeyTests, 26 | ReturnsTrueWhenMapHasKey) { 27 | std::map map{ 28 | {1, 2} 29 | }; 30 | 31 | ASSERT_TRUE(hasKey(map, 1)); 32 | } 33 | 34 | TEST_F(HasKeyTests, 35 | ReturnsFalseWhenMapDoesNotHaveKey) { 36 | std::map map; 37 | 38 | ASSERT_FALSE(hasKey(map, 1)); 39 | } 40 | 41 | /// 42 | /// Tests for getValue(). 43 | /// 44 | class GetValueTests: public Test {}; 45 | 46 | TEST_F(GetValueTests, 47 | ReturnsValueWhenMapHasKey) { 48 | std::map map{ 49 | {1, 2} 50 | }; 51 | 52 | ASSERT_EQ(2, getValue(map, 1)); 53 | } 54 | 55 | TEST_F(GetValueTests, 56 | ReturnsDefaultValueWhenMapDoesNotHaveKey) { 57 | std::map map; 58 | 59 | ASSERT_EQ(0, getValue(map, 1)); 60 | } 61 | 62 | } // namespace tests 63 | } // namespace internal 64 | } // namespace retdec 65 | -------------------------------------------------------------------------------- /tests/retdec/internal/utilities/json_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/json_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for string utilities. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/exceptions.h" 11 | #include "retdec/internal/utilities/json.h" 12 | 13 | using namespace testing; 14 | 15 | namespace retdec { 16 | namespace internal { 17 | namespace tests { 18 | 19 | /// 20 | /// Tests for JsonDecodingError. 21 | /// 22 | class JsonDecodingErrorTests: public Test {}; 23 | 24 | TEST_F(JsonDecodingErrorTests, 25 | WhatReturnsCorrectMessage) { 26 | const std::string RefFormattedErrors("line 1 column 1"); 27 | JsonDecodingError e(RefFormattedErrors); 28 | 29 | ASSERT_EQ("JSON decoding failed: " + RefFormattedErrors, e.what()); 30 | } 31 | 32 | /// 33 | /// Tests for toJson(). 34 | /// 35 | class ToJsonTests: public Test {}; 36 | 37 | TEST_F(ToJsonTests, 38 | StringAsJsonIsParsedCorrectly) { 39 | auto asJson = toJson("\"text\""); 40 | 41 | ASSERT_EQ("text", asJson.asString()); 42 | } 43 | 44 | TEST_F(ToJsonTests, 45 | ObjectAsJsonIsParsedCorrectly) { 46 | auto asJson = toJson("{\"id\": 1}"); 47 | 48 | ASSERT_TRUE(asJson.isMember("id")); 49 | ASSERT_EQ(1, asJson.size()); 50 | ASSERT_EQ(1, asJson.get("id", 0).asInt()); 51 | } 52 | 53 | TEST_F(ToJsonTests, 54 | ThrowsJsonDecodingErrorWhenStringIsInvalid) { 55 | ASSERT_THROW(toJson("{xxx}"), JsonDecodingError); 56 | } 57 | 58 | } // namespace tests 59 | } // namespace internal 60 | } // namespace retdec 61 | -------------------------------------------------------------------------------- /tests/retdec/internal/utilities/os_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/os_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for operating-system-related utilities. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/exceptions.h" 11 | #include "retdec/internal/utilities/os.h" 12 | #include "retdec/test_utilities/tmp_file.h" 13 | 14 | using namespace testing; 15 | using namespace retdec::tests; 16 | 17 | namespace retdec { 18 | namespace internal { 19 | namespace tests { 20 | 21 | /// 22 | /// Tests for fileNameFromPath(). 23 | /// 24 | class FileNameFromPathTests: public Test {}; 25 | 26 | TEST_F(FileNameFromPathTests, 27 | FileNameFromPathReturnsCorrectNameForPathWithSeparators) { 28 | #ifdef RETDEC_OS_WINDOWS 29 | ASSERT_EQ("file.txt", fileNameFromPath(R"(C:\\path\to\file.txt)")); 30 | #else 31 | ASSERT_EQ("file.txt", fileNameFromPath("/path/to/file.txt")); 32 | #endif 33 | } 34 | 35 | TEST_F(FileNameFromPathTests, 36 | FileNameFromPathContainingJustFileNameReturnsCorrectFileName) { 37 | ASSERT_EQ("file.txt", fileNameFromPath("file.txt")); 38 | } 39 | 40 | TEST_F(FileNameFromPathTests, 41 | FileNameFromPathContainingNoFileNameReturnsEmptyString) { 42 | #ifdef RETDEC_OS_WINDOWS 43 | ASSERT_EQ("", fileNameFromPath(R"(C:\\path\to\dir\)")); 44 | #else 45 | ASSERT_EQ("", fileNameFromPath("/path/to/dir/")); 46 | #endif 47 | } 48 | 49 | /// 50 | /// Tests for readFile(). 51 | /// 52 | class ReadFileTests: public Test {}; 53 | 54 | TEST_F(ReadFileTests, 55 | ReturnsCorrectContentWhenFileExists) { 56 | auto tmpFile = TmpFile::createWithContent("content"); 57 | 58 | ASSERT_EQ("content", readFile(tmpFile->getPath())); 59 | } 60 | 61 | TEST_F(ReadFileTests, 62 | ThrowsFilesystemErrorWhenFileDoesNotExist) { 63 | ASSERT_THROW(readFile("nonexisting-file"), FilesystemError); 64 | } 65 | 66 | /// 67 | /// Tests for writeFile(). 68 | /// 69 | class WriteFileTests: public Test {}; 70 | 71 | TEST_F(WriteFileTests, 72 | WritesCorrectContentToFile) { 73 | const std::string Content{"content"}; 74 | auto tmpFile = TmpFile::createWithContent(""); 75 | 76 | writeFile(tmpFile->getPath(), Content); 77 | 78 | ASSERT_EQ(Content, readFile(tmpFile->getPath())); 79 | } 80 | 81 | TEST_F(WriteFileTests, 82 | ThrowsIoErrorWhenFileCannotBeOpenedForWriting) { 83 | ASSERT_THROW(writeFile("/", "content"), IoError); 84 | } 85 | 86 | /// 87 | /// Tests for copyFile(). 88 | /// 89 | class CopyFileTests: public Test {}; 90 | 91 | TEST_F(CopyFileTests, 92 | WritesCorrectContentToFile) { 93 | const std::string Content{"content"}; 94 | auto tmpInFile = TmpFile::createWithContent(Content); 95 | auto tmpOutFile = TmpFile::createWithContent(""); 96 | 97 | copyFile(tmpInFile->getPath(), tmpOutFile->getPath()); 98 | 99 | ASSERT_EQ(Content, readFile(tmpOutFile->getPath())); 100 | } 101 | 102 | TEST_F(CopyFileTests, 103 | ThrowsFilesystemErrorWhenSourceFileDoesNotExist) { 104 | ASSERT_THROW(copyFile("nonexisting-file", "any-file"), FilesystemError); 105 | } 106 | 107 | } // namespace tests 108 | } // namespace internal 109 | } // namespace retdec 110 | -------------------------------------------------------------------------------- /tests/retdec/internal/utilities/smart_ptr_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/smart_ptr_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for smart pointer utilities. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/utilities/smart_ptr.h" 11 | 12 | using namespace testing; 13 | 14 | namespace retdec { 15 | namespace internal { 16 | namespace tests { 17 | 18 | /// 19 | /// Tests for smart pointer utilities. 20 | /// 21 | class SmartPtrTests: public Test {}; 22 | 23 | } // namespace tests 24 | } // namespace internal 25 | } // namespace retdec 26 | -------------------------------------------------------------------------------- /tests/retdec/internal/utilities/string_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/internal/utilities/string_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for string utilities. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/utilities/string.h" 11 | 12 | using namespace testing; 13 | 14 | namespace retdec { 15 | namespace internal { 16 | namespace tests { 17 | 18 | /// 19 | /// Tests for capitalizeWords(). 20 | /// 21 | class CapitalizeWordsTests: public Test {}; 22 | 23 | TEST_F(CapitalizeWordsTests, 24 | SingleLowercaseWordIsCapitalizedCorrectly) { 25 | ASSERT_EQ("Test", capitalizeWords("test")); 26 | } 27 | 28 | TEST_F(CapitalizeWordsTests, 29 | TwoLowercaseWordsAreCapitalizedCorrectly) { 30 | ASSERT_EQ("Test Me", capitalizeWords("test me")); 31 | } 32 | 33 | TEST_F(CapitalizeWordsTests, 34 | TwoUppercaseWordsAreCapitalizedCorrectly) { 35 | ASSERT_EQ("Test Me", capitalizeWords("TEST ME")); 36 | } 37 | 38 | TEST_F(CapitalizeWordsTests, 39 | TwoMixedcaseWordsAreCapitalizedCorrectly) { 40 | ASSERT_EQ("Test Me", capitalizeWords("tEsT mE")); 41 | } 42 | 43 | TEST_F(CapitalizeWordsTests, 44 | ManyWordsAreCapitalizedCorrectly) { 45 | ASSERT_EQ("My Name Is Jerry", capitalizeWords("my name is jerry")); 46 | } 47 | 48 | TEST_F(CapitalizeWordsTests, 49 | WhitespaceIsPreserved) { 50 | ASSERT_EQ(" Test \t Me\n", capitalizeWords(" test \t me\n")); 51 | } 52 | 53 | TEST_F(CapitalizeWordsTests, 54 | WordsBeginningWithNonAlphanumericCharactersAreNotModified) { 55 | ASSERT_EQ("5abc", capitalizeWords("5abc")); 56 | ASSERT_EQ(".abc", capitalizeWords(".abc")); 57 | } 58 | 59 | } // namespace tests 60 | } // namespace internal 61 | } // namespace retdec 62 | -------------------------------------------------------------------------------- /tests/retdec/resource_arguments_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/resource_arguments_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the base class of arguments for all services. 6 | /// 7 | 8 | #include 9 | #include 10 | 11 | #include "retdec/resource_arguments.h" 12 | #include "retdec/file_mock.h" 13 | 14 | using namespace testing; 15 | 16 | namespace retdec { 17 | namespace tests { 18 | 19 | /// 20 | /// Tests for ResourceArguments. 21 | /// 22 | class ResourceArgumentsTests: public Test {}; 23 | 24 | // Generic access to arguments. 25 | 26 | TEST_F(ResourceArgumentsTests, 27 | ArgumentSetsNewArgumentInPlace) { 28 | ResourceArguments args; 29 | 30 | args.argument("id", "value"); 31 | 32 | ASSERT_EQ("value", args.argument("id")); 33 | } 34 | 35 | TEST_F(ResourceArgumentsTests, 36 | WithArgumentReturnsNewArgumentsWithCorrectArgument) { 37 | ResourceArguments args; 38 | 39 | auto newArgs = args.withArgument("id", "value"); 40 | 41 | ASSERT_EQ("value", newArgs.argument("id")); 42 | } 43 | 44 | TEST_F(ResourceArgumentsTests, 45 | HasArgumentReturnsTrueWhenArgumentIsSet) { 46 | auto args = ResourceArguments() 47 | .withArgument("id", "value"); 48 | 49 | ASSERT_TRUE(args.hasArgument("id")); 50 | } 51 | 52 | TEST_F(ResourceArgumentsTests, 53 | HasArgumentReturnsFalseWhenArgumentIsNotSet) { 54 | ResourceArguments args; 55 | 56 | ASSERT_FALSE(args.hasArgument("id")); 57 | } 58 | 59 | TEST_F(ResourceArgumentsTests, 60 | IterationOverArgumentsWorksCorrectly) { 61 | auto args = ResourceArguments() 62 | .withArgument("id1", "value1") 63 | .withArgument("id2", "value2"); 64 | 65 | auto it = args.argumentsBegin(); 66 | ASSERT_EQ("id1", it->first); 67 | ASSERT_EQ("value1", it->second); 68 | ++it; 69 | ASSERT_EQ("id2", it->first); 70 | ASSERT_EQ("value2", it->second); 71 | ++it; 72 | ASSERT_EQ(args.argumentsEnd(), it); 73 | } 74 | 75 | // Generic access to files. 76 | 77 | TEST_F(ResourceArgumentsTests, 78 | FileSetsNewFileInPlace) { 79 | ResourceArguments args; 80 | auto file = std::make_shared(); 81 | 82 | args.file("id", file); 83 | 84 | ASSERT_EQ(file, args.file("id")); 85 | } 86 | 87 | TEST_F(ResourceArgumentsTests, 88 | WithFileReturnsNewFilesWithCorrectFile) { 89 | ResourceArguments args; 90 | auto file = std::make_shared(); 91 | 92 | auto newArgs = args.withFile("id", file); 93 | 94 | ASSERT_EQ(file, newArgs.file("id")); 95 | } 96 | 97 | TEST_F(ResourceArgumentsTests, 98 | HasFileReturnsTrueWhenFileIsSet) { 99 | auto args = ResourceArguments() 100 | .withFile("id", std::make_shared()); 101 | ASSERT_TRUE(args.hasFile("id")); 102 | 103 | } 104 | 105 | TEST_F(ResourceArgumentsTests, 106 | HasFileReturnsFalseWhenFileIsNotSet) { 107 | ResourceArguments args; 108 | 109 | ASSERT_FALSE(args.hasFile("id")); 110 | } 111 | 112 | TEST_F(ResourceArgumentsTests, 113 | IterationOverFilesWorksCorrectly) { 114 | auto file1 = std::make_shared(); 115 | auto file2 = std::make_shared(); 116 | auto args = ResourceArguments() 117 | .withFile("id1", file1) 118 | .withFile("id2", file2); 119 | 120 | auto it = args.filesBegin(); 121 | ASSERT_EQ("id1", it->first); 122 | ASSERT_EQ(file1, it->second); 123 | ++it; 124 | ASSERT_EQ("id2", it->first); 125 | ASSERT_EQ(file2, it->second); 126 | ++it; 127 | ASSERT_EQ(args.filesEnd(), it); 128 | } 129 | 130 | // Chaining. 131 | 132 | TEST_F(ResourceArgumentsTests, 133 | InPlaceSettersAllowChainingForLValue) { 134 | ResourceArguments args; 135 | 136 | args.argument("id1", "value1") 137 | .argument("id2", "value2"); 138 | 139 | ASSERT_EQ("value1", args.argument("id1")); 140 | ASSERT_EQ("value2", args.argument("id2")); 141 | } 142 | 143 | TEST_F(ResourceArgumentsTests, 144 | InPlaceSettersAllowChainingForRValue) { 145 | auto args = ResourceArguments() 146 | .argument("id1", "value1") 147 | .argument("id2", "value2"); 148 | 149 | ASSERT_EQ("value1", args.argument("id1")); 150 | ASSERT_EQ("value2", args.argument("id2")); 151 | } 152 | 153 | TEST_F(ResourceArgumentsTests, 154 | NotModifyingSettersAllowChaining) { 155 | auto args = ResourceArguments() 156 | .withArgument("id1", "value1") 157 | .withArgument("id2", "value2"); 158 | 159 | ASSERT_EQ("value1", args.argument("id1")); 160 | ASSERT_EQ("value2", args.argument("id2")); 161 | } 162 | 163 | } // namespace tests 164 | } // namespace retdec 165 | -------------------------------------------------------------------------------- /tests/retdec/settings_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/settings_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the settings. 6 | /// 7 | 8 | #include 9 | 10 | #include "retdec/internal/utilities/os.h" 11 | #include "retdec/settings.h" 12 | 13 | using namespace testing; 14 | using namespace retdec::internal; 15 | 16 | namespace retdec { 17 | namespace tests { 18 | 19 | /// 20 | /// Tests for Settings. 21 | /// 22 | class SettingsTests: public Test {}; 23 | 24 | TEST_F(SettingsTests, 25 | DefaultApiUrlHasCorrectValue) { 26 | ASSERT_EQ("https://retdec.com/service/api", Settings::DefaultApiUrl); 27 | } 28 | 29 | TEST_F(SettingsTests, 30 | DefaultApiKeyHasCorrectValue) { 31 | ASSERT_EQ("", Settings::DefaultApiKey); 32 | } 33 | 34 | TEST_F(SettingsTests, 35 | DefaultUserAgentHasCorrectValue) { 36 | ASSERT_EQ("retdec-cpp/" + operatingSystemName(), Settings::DefaultUserAgent); 37 | } 38 | 39 | TEST_F(SettingsTests, 40 | HasDefaultValuesWhenCreatedWithDefaultConstructor) { 41 | Settings settings; 42 | 43 | ASSERT_EQ(Settings::DefaultApiKey, settings.apiKey()); 44 | ASSERT_EQ(Settings::DefaultApiUrl, settings.apiUrl()); 45 | ASSERT_EQ(Settings::DefaultUserAgent, settings.userAgent()); 46 | } 47 | 48 | TEST_F(SettingsTests, 49 | ApiKeyChangesSettingsInPlace) { 50 | Settings settings; 51 | 52 | settings.apiKey("my-api-key"); 53 | 54 | ASSERT_EQ("my-api-key", settings.apiKey()); 55 | } 56 | 57 | TEST_F(SettingsTests, 58 | WithApiKeyReturnsSettingsWithNewApiKey) { 59 | Settings settings; 60 | 61 | auto newSettings = settings.withApiKey("my-api-key"); 62 | 63 | ASSERT_EQ("my-api-key", newSettings.apiKey()); 64 | } 65 | 66 | TEST_F(SettingsTests, 67 | ApiUrlChangesSettingsInPlace) { 68 | Settings settings; 69 | 70 | settings.apiUrl("http://127.0.0.1/api"); 71 | 72 | ASSERT_EQ("http://127.0.0.1/api", settings.apiUrl()); 73 | } 74 | 75 | TEST_F(SettingsTests, 76 | WithApiUrlReturnsSettingsWithNewApiUrl) { 77 | Settings settings; 78 | 79 | auto newSettings = settings.withApiUrl("http://127.0.0.1/api"); 80 | 81 | ASSERT_EQ("http://127.0.0.1/api", newSettings.apiUrl()); 82 | } 83 | 84 | TEST_F(SettingsTests, 85 | UserAgentChangesSettingsInPlace) { 86 | Settings settings; 87 | 88 | settings.userAgent("my user agent"); 89 | 90 | ASSERT_EQ("my user agent", settings.userAgent()); 91 | } 92 | 93 | TEST_F(SettingsTests, 94 | WithUserAgentReturnsSettingsWithNewUserAgent) { 95 | Settings settings; 96 | 97 | auto newSettings = settings.withUserAgent("my user agent"); 98 | 99 | ASSERT_EQ("my user agent", newSettings.userAgent()); 100 | } 101 | 102 | TEST_F(SettingsTests, 103 | NotModifyingSettersAllowChaining) { 104 | auto settings = Settings() 105 | .withApiKey("my-api-key") 106 | .withApiUrl("http://127.0.0.1/api"); 107 | 108 | ASSERT_EQ("my-api-key", settings.apiKey()); 109 | ASSERT_EQ("http://127.0.0.1/api", settings.apiUrl()); 110 | } 111 | 112 | TEST_F(SettingsTests, 113 | InPlaceSettersAllowChainingForLValue) { 114 | Settings settings; 115 | 116 | settings.apiKey("my-api-key") 117 | .apiUrl("http://127.0.0.1/api"); 118 | 119 | ASSERT_EQ("my-api-key", settings.apiKey()); 120 | ASSERT_EQ("http://127.0.0.1/api", settings.apiUrl()); 121 | } 122 | 123 | TEST_F(SettingsTests, 124 | InPlaceSettersAllowChainingForRValue) { 125 | auto settings = Settings() 126 | .apiKey("my-api-key") 127 | .apiUrl("http://127.0.0.1/api"); 128 | 129 | ASSERT_EQ("my-api-key", settings.apiKey()); 130 | ASSERT_EQ("http://127.0.0.1/api", settings.apiUrl()); 131 | } 132 | 133 | } // namespace tests 134 | } // namespace retdec 135 | -------------------------------------------------------------------------------- /tests/retdec/test_tests.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/test_tests.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Tests for the testing service. 6 | /// 7 | 8 | #include 9 | #include 10 | 11 | #include "retdec/exceptions.h" 12 | #include "retdec/internal/connection_manager_mock.h" 13 | #include "retdec/internal/connection_mock.h" 14 | #include "retdec/internal/utilities/json.h" 15 | #include "retdec/settings.h" 16 | #include "retdec/test.h" 17 | 18 | using namespace retdec::internal::tests; 19 | using namespace retdec::internal; 20 | using testing::NiceMock; 21 | using testing::Return; 22 | using testing::_; 23 | 24 | namespace retdec { 25 | namespace tests { 26 | 27 | /// 28 | /// Tests for Test. 29 | /// 30 | class TestTests: public testing::Test {}; 31 | 32 | TEST_F(TestTests, 33 | IsCreatedSuccessfullyWithDefaultConnectionManager) { 34 | retdec::Test test{ 35 | Settings() 36 | }; 37 | } 38 | 39 | TEST_F(TestTests, 40 | IsCreatedSuccessfullyWithCustomConnectionManager) { 41 | auto connectionManager = std::make_shared(); 42 | retdec::Test test( 43 | Settings(), 44 | connectionManager 45 | ); 46 | } 47 | 48 | /// 49 | /// Tests for Test::auth(). 50 | /// 51 | class TestAuthTests: public testing::Test { 52 | public: 53 | virtual void SetUp() override; 54 | 55 | std::unique_ptr response = 56 | std::make_unique(); 57 | 58 | std::shared_ptr conn = 59 | std::make_shared(); 60 | 61 | std::shared_ptr> connectionManager = 62 | std::make_shared>(); 63 | 64 | std::unique_ptr test = std::make_unique( 65 | Settings() 66 | .apiKey("API-KEY"), 67 | connectionManager 68 | ); 69 | }; 70 | 71 | void TestAuthTests::SetUp() { 72 | ON_CALL(*connectionManager, newConnection(_)) 73 | .WillByDefault(Return(conn)); 74 | } 75 | 76 | TEST_F(TestAuthTests, 77 | AuthDoesNotThrowAuthErrorWhenAuthSucceeded) { 78 | EXPECT_CALL(*response, statusCode()) 79 | .WillOnce(Return(200)); // HTTP 200 OK 80 | EXPECT_CALL(*conn, sendGetRequestProxy( 81 | "https://retdec.com/service/api/test/echo")) 82 | .WillOnce(Return(response.release())); 83 | 84 | test->auth(); 85 | } 86 | 87 | TEST_F(TestAuthTests, 88 | AuthThrowsAuthErrorWhenAuthFailed) { 89 | EXPECT_CALL(*response, statusCode()) 90 | .WillRepeatedly(Return(401)); // HTTP 401 Unauthorized 91 | EXPECT_CALL(*response, statusMessage()) 92 | .WillOnce(Return("Unauthorized")); 93 | EXPECT_CALL(*response, bodyAsJson()) 94 | .WillOnce(Return(toJson(R"( 95 | { 96 | "code": 401, 97 | "message": "Unauthorized", 98 | "description": "Unauthorized." 99 | } 100 | )"))); 101 | EXPECT_CALL(*conn, sendGetRequestProxy( 102 | "https://retdec.com/service/api/test/echo")) 103 | .WillOnce(Return(response.release())); 104 | 105 | try { 106 | test->auth(); 107 | FAIL() << "expected AuthError to be thrown"; 108 | } catch (const AuthError &ex) { 109 | ASSERT_EQ(401, ex.getCode()); 110 | ASSERT_EQ("Unauthorized", ex.getMessage()); 111 | } 112 | } 113 | 114 | } // namespace tests 115 | } // namespace retdec 116 | -------------------------------------------------------------------------------- /tests/retdec/test_utilities/tmp_file.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/test_utilities/tmp_file.cpp 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Implementation of the temporary file utilities. 6 | /// 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "retdec/test_utilities/tmp_file.h" 14 | 15 | namespace retdec { 16 | namespace tests { 17 | 18 | /// 19 | /// Private implementation of TmpFile. 20 | /// 21 | struct TmpFile::Impl { 22 | /// Creates a temporary file with the given content. 23 | Impl(): path(boost::filesystem::unique_path()) {} 24 | 25 | /// Path to the temporary file. 26 | boost::filesystem::path path; 27 | }; 28 | 29 | /// 30 | /// Creates a temporary file with the given content. 31 | /// 32 | TmpFile::TmpFile(const std::string &content): impl(std::make_unique()) { 33 | std::ofstream file(impl->path.native(), std::ios::out | std::ios::binary); 34 | file << content; 35 | } 36 | 37 | /// 38 | /// Destroys the temporary file by removing it. 39 | /// 40 | TmpFile::~TmpFile() { 41 | boost::filesystem::remove(impl->path); 42 | } 43 | 44 | /// 45 | /// Returns a path to the file. 46 | /// 47 | std::string TmpFile::getPath() const { 48 | return impl->path.native(); 49 | } 50 | 51 | /// 52 | /// Creates a temporary file with the given content. 53 | /// 54 | std::unique_ptr TmpFile::createWithContent(const std::string &content) { 55 | return std::unique_ptr(new TmpFile(content)); 56 | } 57 | 58 | RemoveFileOnDestruction::RemoveFileOnDestruction(const std::string &path): 59 | path(path) {} 60 | 61 | RemoveFileOnDestruction::~RemoveFileOnDestruction() { 62 | boost::filesystem::remove(path); 63 | } 64 | 65 | } // namespace tests 66 | } // namespace retdec 67 | -------------------------------------------------------------------------------- /tests/retdec/test_utilities/tmp_file.h: -------------------------------------------------------------------------------- 1 | /// 2 | /// @file retdec/test_utilities/tmp_file.h 3 | /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors 4 | /// @license MIT, see the @c LICENSE file for more details 5 | /// @brief Temporary file utilities. 6 | /// 7 | 8 | #include 9 | #include 10 | 11 | namespace retdec { 12 | namespace tests { 13 | 14 | /// 15 | /// A temporary file that is automatically deleted when destructed. 16 | /// 17 | class TmpFile { 18 | public: 19 | ~TmpFile(); 20 | 21 | std::string getPath() const; 22 | 23 | static std::unique_ptr createWithContent( 24 | const std::string &content); 25 | 26 | private: 27 | TmpFile(const std::string &content); 28 | 29 | private: 30 | struct Impl; 31 | /// Private implementation. 32 | std::unique_ptr impl; 33 | }; 34 | 35 | /// 36 | /// RAII helper that removes the given file in its destructor. 37 | /// 38 | class RemoveFileOnDestruction { 39 | public: 40 | RemoveFileOnDestruction(const std::string &path); 41 | ~RemoveFileOnDestruction(); 42 | 43 | private: 44 | /// Path to the file to be removed. 45 | const std::string path; 46 | }; 47 | 48 | } // namespace tests 49 | } // namespace retdec 50 | --------------------------------------------------------------------------------