├── .gitignore ├── .ignore ├── .travis.yml ├── AUTHORS ├── CMakeLists.txt ├── Dockerfile ├── LICENSE ├── README.md ├── appveyor.yml ├── cmake ├── CheckTemplate.cmake ├── ClangTidy.cmake ├── CompileOptions.cmake ├── ComponentInstall.cmake ├── Cppcheck.cmake ├── Custom.cmake ├── FindASSIMP.cmake ├── FindFFMPEG.cmake ├── FindGLEW.cmake ├── FindGLFW.cmake ├── FindGLM.cmake ├── FindLibCrypto.cmake ├── FindLibSSH2.cmake ├── Findclang_tidy.cmake ├── Findcppcheck.cmake ├── Findgoogletest.cmake ├── Findnodejs.cmake ├── GetGitRevisionDescription.cmake ├── GetGitRevisionDescription.cmake.in ├── HealthCheck.cmake └── RuntimeDependencies.cmake ├── configure ├── cppfs-config.cmake ├── cppfs-logo.png ├── cppfs-logo.svg ├── deploy ├── CMakeLists.txt ├── packages │ └── pack-cppfs.cmake └── ubuntu-ppa │ ├── debian │ ├── changelog │ ├── compat │ ├── control │ ├── copyright │ ├── rules │ └── source │ │ └── format │ └── recipe.txt ├── docs ├── CMakeLists.txt └── api-docs │ ├── CMakeLists.txt │ └── doxyfile.in └── source ├── CMakeLists.txt ├── cppfs ├── 3rdparty │ └── basen │ │ ├── LICENSE │ │ ├── README.md │ │ └── basen.hpp ├── CMakeLists.txt ├── include │ └── cppfs │ │ ├── AbstractFileHandleBackend.h │ │ ├── AbstractFileIteratorBackend.h │ │ ├── AbstractFileSystem.h │ │ ├── AbstractFileWatcherBackend.h │ │ ├── Change.h │ │ ├── Diff.h │ │ ├── FileEventHandler.h │ │ ├── FileHandle.h │ │ ├── FileIterator.h │ │ ├── FilePath.h │ │ ├── FileVisitor.h │ │ ├── FileWatcher.h │ │ ├── FunctionalFileEventHandler.h │ │ ├── FunctionalFileVisitor.h │ │ ├── InputStream.h │ │ ├── LoginCredentials.h │ │ ├── OutputStream.h │ │ ├── Tree.h │ │ ├── Url.h │ │ ├── cppfs.h │ │ ├── fs.h │ │ ├── linux │ │ └── LocalFileWatcher.h │ │ ├── posix │ │ ├── LocalFileHandle.h │ │ ├── LocalFileIterator.h │ │ └── LocalFileSystem.h │ │ ├── ssh │ │ ├── SshFileHandle.h │ │ ├── SshFileIterator.h │ │ ├── SshFileSystem.h │ │ ├── SshInputStreamBuffer.h │ │ └── SshOutputStreamBuffer.h │ │ ├── system.h │ │ ├── units.h │ │ └── windows │ │ ├── LocalFileHandle.h │ │ ├── LocalFileIterator.h │ │ ├── LocalFileSystem.h │ │ └── LocalFileWatcher.h └── source │ ├── AbstractFileHandleBackend.cpp │ ├── AbstractFileIteratorBackend.cpp │ ├── AbstractFileSystem.cpp │ ├── AbstractFileWatcherBackend.cpp │ ├── Change.cpp │ ├── Diff.cpp │ ├── FileEventHandler.cpp │ ├── FileHandle.cpp │ ├── FileIterator.cpp │ ├── FilePath.cpp │ ├── FileVisitor.cpp │ ├── FileWatcher.cpp │ ├── FunctionalFileEventHandler.cpp │ ├── FunctionalFileVisitor.cpp │ ├── InputStream.cpp │ ├── LoginCredentials.cpp │ ├── OutputStream.cpp │ ├── Tree.cpp │ ├── Url.cpp │ ├── fs.cpp │ ├── linux │ └── LocalFileWatcher.cpp │ ├── posix │ ├── LocalFileHandle.cpp │ ├── LocalFileIterator.cpp │ └── LocalFileSystem.cpp │ ├── ssh │ ├── SshFileHandle.cpp │ ├── SshFileIterator.cpp │ ├── SshFileSystem.cpp │ ├── SshInputStreamBuffer.cpp │ └── SshOutputStreamBuffer.cpp │ ├── system.cpp │ └── windows │ ├── LocalFileHandle.cpp │ ├── LocalFileIterator.cpp │ ├── LocalFileSystem.cpp │ └── LocalFileWatcher.cpp ├── examples ├── CMakeLists.txt ├── cppfs-cat │ ├── CMakeLists.txt │ └── main.cpp ├── cppfs-cp │ ├── CMakeLists.txt │ └── main.cpp ├── cppfs-ln │ ├── CMakeLists.txt │ └── main.cpp ├── cppfs-ls │ ├── CMakeLists.txt │ └── main.cpp ├── cppfs-sync │ ├── CMakeLists.txt │ └── main.cpp ├── cppfs-tree │ ├── CMakeLists.txt │ └── main.cpp └── cppfs-watch │ ├── CMakeLists.txt │ └── main.cpp ├── scripts ├── CMakeLists.txt └── check_template.sh ├── tests ├── CMakeLists.txt └── cppfs-test │ ├── CMakeLists.txt │ ├── FilePath_test.cpp │ └── main.cpp └── version.h.in /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | *.dylib 9 | 10 | # Compiled Static libraries 11 | *.lai 12 | *.la 13 | *.a 14 | 15 | # Build dir 16 | *-build* 17 | build* 18 | debug_build 19 | release_build 20 | /bin 21 | /lib 22 | /install 23 | 24 | # Qt cache 25 | CMakeLists.txt.user 26 | CMakeLists.txt.user.* 27 | 28 | # IDE project files 29 | *.sublime-project 30 | *.sublime-workspace 31 | .vscode 32 | 33 | # Local config windows 34 | _configure.bat 35 | _open-project.bat 36 | _start-cmake-gui.bat 37 | _start-cmd.bat 38 | 39 | # Local config unix 40 | .localconfig 41 | -------------------------------------------------------------------------------- /.ignore: -------------------------------------------------------------------------------- 1 | source/tests/googletest/* 2 | source/cppfs/3rdparty/* 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | env: 4 | global: 5 | - CMAKE_OPTIONS="-DOPTION_BUILD_EXAMPLES=On" 6 | 7 | matrix: 8 | include: 9 | 10 | - os: linux 11 | compiler: clang 12 | env: CMAKE_CONFIGURATION=release BUILD_DIR=build 13 | addons: 14 | apt: 15 | sources: 16 | - sourceline: 'ppa:cginternals/backports-ppa' 17 | packages: 18 | - libssh2-1-dev 19 | - lib64z1-dev 20 | - libssl-dev 21 | - cppcheck 22 | - clang-tidy-3.8 23 | - libcppassist-dev 24 | 25 | - os: linux 26 | compiler: clang 27 | env: CMAKE_CONFIGURATION=debug BUILD_DIR=build-debug 28 | addons: 29 | apt: 30 | sources: 31 | - sourceline: 'ppa:cginternals/backports-ppa' 32 | packages: 33 | - libssh2-1-dev 34 | - lib64z1-dev 35 | - libssl-dev 36 | - cppcheck 37 | - clang-tidy-3.8 38 | - libcppassist-dev 39 | 40 | - os: linux 41 | compiler: gcc 42 | env: 43 | - CMAKE_CONFIGURATION=release BUILD_DIR=build 44 | - MATRIX_EVAL="CC=gcc-5 && CXX=g++-5" 45 | addons: 46 | apt: 47 | sources: 48 | - ubuntu-toolchain-r-test 49 | - sourceline: 'ppa:cginternals/backports-ppa' 50 | packages: 51 | - cmake 52 | - g++-5 53 | - libssh2-1-dev 54 | - lib64z1-dev 55 | - libssl-dev 56 | - cppcheck 57 | - clang-tidy-3.8 58 | - libcppassist-dev 59 | 60 | - os: linux 61 | compiler: gcc 62 | env: 63 | - CMAKE_CONFIGURATION=debug BUILD_DIR=build-debug 64 | - MATRIX_EVAL="CC=gcc-5 && CXX=g++-5" 65 | addons: 66 | apt: 67 | sources: 68 | - ubuntu-toolchain-r-test 69 | - sourceline: 'ppa:cginternals/backports-ppa' 70 | packages: 71 | - cmake 72 | - g++-5 73 | - libssh2-1-dev 74 | - lib64z1-dev 75 | - libssl-dev 76 | - cppcheck 77 | - clang-tidy-3.8 78 | - libcppassist-dev 79 | 80 | before_install: 81 | - if [ $TRAVIS_OS_NAME == linux ]; then export CMAKE_OPTIONS="$CMAKE_OPTIONS"; fi 82 | - if [ $TRAVIS_OS_NAME == linux ]; then echo "CMAKE_OPTIONS = $CMAKE_OPTIONS"; fi 83 | 84 | before_script: 85 | - eval "${MATRIX_EVAL}" 86 | - chmod +x ./configure 87 | - ./configure 88 | - ./configure $CMAKE_CONFIGURATION 89 | 90 | script: 91 | - cmake --build $BUILD_DIR 92 | - cmake --build $BUILD_DIR --target test 93 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | 2 | Stefan Buschmann 3 | Daniel Limberger 4 | Willy Scheibel 5 | 6 | 7 | Thanks to all Contributors: 8 | 9 | Robert Bielik (https://github.com/robiwano) 10 | kwallner (https://github.com/kwallner) 11 | gabm (https://github.com/gabm) 12 | Christopher Weyand (https://github.com/chistopher) 13 | Hailios (https://github.com/Hailios) 14 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE=cginternals/cpp-base:latest 2 | ARG BASE_DEV=cginternals/cpp-base:dev 3 | ARG PROJECT_NAME=cppfs 4 | 5 | # BUILD 6 | 7 | FROM $BASE_DEV AS build 8 | 9 | ARG PROJECT_NAME 10 | ARG COMPILER_FLAGS="-j 4" 11 | 12 | ENV cppfs_DIR="$WORKSPACE/$PROJECT_NAME" 13 | 14 | WORKDIR $WORKSPACE/$PROJECT_NAME 15 | 16 | ADD cmake cmake 17 | ADD docs docs 18 | ADD deploy deploy 19 | ADD source source 20 | ADD CMakeLists.txt CMakeLists.txt 21 | ADD configure configure 22 | ADD $PROJECT_NAME-config.cmake $PROJECT_NAME-config.cmake 23 | ADD $PROJECT_NAME-logo.png $PROJECT_NAME-logo.png 24 | ADD $PROJECT_NAME-logo.svg $PROJECT_NAME-logo.svg 25 | ADD LICENSE LICENSE 26 | ADD README.md README.md 27 | ADD AUTHORS AUTHORS 28 | 29 | RUN ./configure 30 | RUN CMAKE_OPTIONS="-DOPTION_BUILD_TESTS=Off" ./configure 31 | RUN cmake --build build -- $COMPILER_FLAGS 32 | 33 | # INSTALL 34 | 35 | FROM build as install 36 | 37 | ARG PROJECT_NAME 38 | 39 | WORKDIR $WORKSPACE/$PROJECT_NAME 40 | 41 | RUN CMAKE_OPTIONS="-DCMAKE_INSTALL_PREFIX=$WORKSPACE/$PROJECT_NAME-install" ./configure 42 | RUN cmake --build build --target install 43 | 44 | # DEPLOY 45 | 46 | FROM $BASE AS deploy 47 | 48 | ARG PROJECT_NAME 49 | 50 | ENV cppfs_DIR="$WORKSPACE/$PROJECT_NAME" 51 | 52 | COPY --from=install $WORKSPACE/$PROJECT_NAME-install $WORKSPACE/$PROJECT_NAME 53 | 54 | ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$WORKSPACE/$PROJECT_NAME/lib 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2017-2017 CG Internals GmbH 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{build}' 2 | branches: 3 | only: 4 | - master 5 | clone_folder: c:\projects\cppfs 6 | image: 7 | - Visual Studio 2013 8 | - Visual Studio 2015 9 | - Visual Studio 2017 10 | configuration: 11 | - Release 12 | - Debug 13 | platform: 14 | - x64 15 | environment: 16 | matrix: 17 | - arch: Win64 18 | # - arch: #does not work, Release|x64 not a valid target 19 | matrix: 20 | fast_finish: true 21 | 22 | # skip unsupported combinations 23 | init: 24 | - set arch= 25 | - if "%arch%"=="Win64" ( set arch= Win64) 26 | - echo %arch% 27 | - echo %APPVEYOR_BUILD_WORKER_IMAGE% 28 | - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" ( set generator="Visual Studio 15 2017%arch%" ) 29 | - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" ( set generator="Visual Studio 14 2015%arch%" ) 30 | - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2013" ( set generator="Visual Studio 12 2013%arch%" ) 31 | - echo %generator% 32 | 33 | before_build: 34 | - cmd: |- 35 | mkdir build 36 | cd build 37 | cmake --version 38 | cmake .. -G %generator% 39 | 40 | build: 41 | project: c:\projects\cppfs\build\cppfs.sln 42 | verbosity: minimal 43 | parallel: true 44 | only_commits: 45 | files: 46 | - CMakeLists.txt 47 | - appveyor.yml 48 | - source/ 49 | - cmake/ 50 | -------------------------------------------------------------------------------- /cmake/CheckTemplate.cmake: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Get cmake-init latest commit SHA on master 4 | # 5 | 6 | file(DOWNLOAD 7 | "https://api.github.com/repos/cginternals/cmake-init/commits/master" 8 | "${PROJECT_BINARY_DIR}/cmake-init.github.data" 9 | ) 10 | file(READ 11 | "${PROJECT_BINARY_DIR}/cmake-init.github.data" 12 | CMAKE_INIT_INFO 13 | ) 14 | 15 | string(REGEX MATCH 16 | "\"sha\": \"([0-9a-f]+)\"," 17 | CMAKE_INIT_SHA 18 | ${CMAKE_INIT_INFO}) 19 | 20 | string(SUBSTRING 21 | ${CMAKE_INIT_SHA} 22 | 8 23 | 40 24 | CMAKE_INIT_SHA 25 | ) 26 | 27 | # 28 | # Get latest cmake-init commit on this repository 29 | # 30 | 31 | # APPLIED_CMAKE_INIT_SHA can be set by parent script 32 | if(NOT APPLIED_CMAKE_INIT_SHA) 33 | # [TODO]: Get from git commit list (see cmake_init/source/scripts/check_template.sh) 34 | set(APPLIED_CMAKE_INIT_SHA "") 35 | endif () 36 | 37 | if("${APPLIED_CMAKE_INIT_SHA}" STREQUAL "") 38 | message(WARNING 39 | "No cmake-init version detected, could not verify up-to-dateness. " 40 | "Set the cmake-init version by defining a META_CMAKE_INIT_SHA for your project." 41 | ) 42 | return() 43 | endif() 44 | 45 | if(${APPLIED_CMAKE_INIT_SHA} STREQUAL ${CMAKE_INIT_SHA}) 46 | message(STATUS "cmake-init template is up-to-date (${CMAKE_INIT_SHA})") 47 | else() 48 | message(STATUS "cmake-init template needs an update https://github.com/cginternals/cmake-init/compare/${APPLIED_CMAKE_INIT_SHA}...master") 49 | endif() 50 | -------------------------------------------------------------------------------- /cmake/ClangTidy.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Function to register a target for clang-tidy 3 | function(perform_clang_tidy check_target target) 4 | set(includes "$") 5 | 6 | add_custom_target( 7 | ${check_target} 8 | COMMAND 9 | ${clang_tidy_EXECUTABLE} 10 | -p\t${PROJECT_BINARY_DIR} 11 | ${ARGN} 12 | -checks=* 13 | "$<$>:--\t$<$:-I$>>" 14 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 15 | ) 16 | 17 | add_dependencies(${check_target} ${target}) 18 | endfunction() 19 | -------------------------------------------------------------------------------- /cmake/CompileOptions.cmake: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Platform and architecture setup 4 | # 5 | 6 | # Get upper case system name 7 | string(TOUPPER ${CMAKE_SYSTEM_NAME} SYSTEM_NAME_UPPER) 8 | 9 | # Determine architecture (32/64 bit) 10 | set(X64 OFF) 11 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) 12 | set(X64 ON) 13 | endif() 14 | 15 | 16 | # 17 | # Project options 18 | # 19 | 20 | set(DEFAULT_PROJECT_OPTIONS 21 | DEBUG_POSTFIX "d" 22 | CXX_STANDARD 11 # Not available before CMake 3.1; see below for manual command line argument addition 23 | LINKER_LANGUAGE "CXX" 24 | POSITION_INDEPENDENT_CODE ON 25 | CXX_VISIBILITY_PRESET "hidden" 26 | ) 27 | 28 | 29 | # 30 | # Include directories 31 | # 32 | 33 | set(DEFAULT_INCLUDE_DIRECTORIES) 34 | 35 | 36 | # 37 | # Libraries 38 | # 39 | 40 | set(DEFAULT_LIBRARIES) 41 | 42 | 43 | # 44 | # Compile definitions 45 | # 46 | 47 | set(DEFAULT_COMPILE_DEFINITIONS 48 | SYSTEM_${SYSTEM_NAME_UPPER} 49 | ) 50 | 51 | # MSVC compiler options 52 | if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") 53 | set(DEFAULT_COMPILE_DEFINITIONS ${DEFAULT_COMPILE_DEFINITIONS} 54 | _SCL_SECURE_NO_WARNINGS # Calling any one of the potentially unsafe methods in the Standard C++ Library 55 | _CRT_SECURE_NO_WARNINGS # Calling any one of the potentially unsafe methods in the CRT Library 56 | ) 57 | endif() 58 | 59 | # MINGW 60 | if (MINGW) 61 | set(DEFAULT_COMPILE_DEFINITIONS ${DEFAULT_COMPILE_DEFINITIONS} 62 | WINVER=0x0600 63 | _WIN32_WINNT=0x0600 64 | ) 65 | endif() 66 | 67 | 68 | # 69 | # Compile options 70 | # 71 | 72 | set(DEFAULT_COMPILE_OPTIONS) 73 | 74 | # MSVC compiler options 75 | if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") 76 | set(DEFAULT_COMPILE_OPTIONS ${DEFAULT_COMPILE_OPTIONS} 77 | /MP # -> build with multiple processes 78 | /W4 # -> warning level 4 79 | # /WX # -> treat warnings as errors 80 | 81 | /wd4251 # -> disable warning: 'identifier': class 'type' needs to have dll-interface to be used by clients of class 'type2' 82 | /wd4592 # -> disable warning: 'identifier': symbol will be dynamically initialized (implementation limitation) 83 | # /wd4201 # -> disable warning: nonstandard extension used: nameless struct/union (caused by GLM) 84 | # /wd4127 # -> disable warning: conditional expression is constant (caused by Qt) 85 | 86 | #$<$: 87 | #/RTCc # -> value is assigned to a smaller data type and results in a data loss 88 | #> 89 | 90 | $<$: 91 | /Gw # -> whole program global optimization 92 | /GS- # -> buffer security check: no 93 | /GL # -> whole program optimization: enable link-time code generation (disables Zi) 94 | /GF # -> enable string pooling 95 | > 96 | 97 | # No manual c++11 enable for MSVC as all supported MSVC versions for cmake-init have C++11 implicitly enabled (MSVC >=2013) 98 | ) 99 | endif () 100 | 101 | # GCC and Clang compiler options 102 | if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") 103 | set(DEFAULT_COMPILE_OPTIONS ${DEFAULT_COMPILE_OPTIONS} 104 | -Wall 105 | -Wextra 106 | -Wunused 107 | 108 | -Wreorder 109 | -Wignored-qualifiers 110 | -Wmissing-braces 111 | -Wreturn-type 112 | -Wswitch 113 | -Wswitch-default 114 | -Wuninitialized 115 | -Wmissing-field-initializers 116 | 117 | $<$: 118 | -Wmaybe-uninitialized 119 | 120 | $<$,4.8>: 121 | -Wpedantic 122 | 123 | -Wreturn-local-addr 124 | > 125 | > 126 | 127 | $<$: 128 | -Wpedantic 129 | 130 | # -Wreturn-stack-address # induce false positives 131 | > 132 | 133 | $<$: 134 | -pthread 135 | > 136 | 137 | # Required for CMake < 3.1; should be removed if minimum required CMake version is raised. 138 | $<$: 139 | -std=c++11 140 | > 141 | ) 142 | endif () 143 | 144 | 145 | # 146 | # Linker options 147 | # 148 | 149 | set(DEFAULT_LINKER_OPTIONS) 150 | 151 | # Use pthreads on mingw and linux 152 | if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_SYSTEM_NAME}" MATCHES "Linux") 153 | set(DEFAULT_LINKER_OPTIONS 154 | -pthread 155 | ) 156 | endif() 157 | -------------------------------------------------------------------------------- /cmake/ComponentInstall.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Execute cmake_install.cmake wrapper that allows to pass both DESTDIR and COMPONENT environment variable 3 | 4 | execute_process( 5 | COMMAND ${CMAKE_COMMAND} -DCOMPONENT=$ENV{COMPONENT} -P cmake_install.cmake 6 | ) 7 | -------------------------------------------------------------------------------- /cmake/Cppcheck.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Function to register a target for cppcheck 3 | function(perform_cppcheck check_target target) 4 | set(includes "$") 5 | 6 | add_custom_target( 7 | ${check_target} 8 | COMMAND 9 | ${cppcheck_EXECUTABLE} 10 | "$<$:-I$>" 11 | --check-config 12 | --enable=warning,performance,portability,information,missingInclude 13 | --quiet 14 | --std=c++11 15 | --verbose 16 | --suppress=missingIncludeSystem 17 | ${ARGN} 18 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 19 | ) 20 | 21 | add_dependencies(${check_target} ${target}) 22 | endfunction() 23 | -------------------------------------------------------------------------------- /cmake/Custom.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Set policy if policy is available 3 | function(set_policy POL VAL) 4 | 5 | if(POLICY ${POL}) 6 | cmake_policy(SET ${POL} ${VAL}) 7 | endif() 8 | 9 | endfunction(set_policy) 10 | 11 | 12 | # Define function "source_group_by_path with three mandatory arguments (PARENT_PATH, REGEX, GROUP, ...) 13 | # to group source files in folders (e.g. for MSVC solutions). 14 | # 15 | # Example: 16 | # source_group_by_path("${CMAKE_CURRENT_SOURCE_DIR}/src" "\\\\.h$|\\\\.inl$|\\\\.cpp$|\\\\.c$|\\\\.ui$|\\\\.qrc$" "Source Files" ${sources}) 17 | function(source_group_by_path PARENT_PATH REGEX GROUP) 18 | 19 | foreach (FILENAME ${ARGN}) 20 | 21 | get_filename_component(FILEPATH "${FILENAME}" REALPATH) 22 | file(RELATIVE_PATH FILEPATH ${PARENT_PATH} ${FILEPATH}) 23 | get_filename_component(FILEPATH "${FILEPATH}" DIRECTORY) 24 | 25 | string(REPLACE "/" "\\" FILEPATH "${FILEPATH}") 26 | 27 | source_group("${GROUP}\\${FILEPATH}" REGULAR_EXPRESSION "${REGEX}" FILES ${FILENAME}) 28 | 29 | endforeach() 30 | 31 | endfunction(source_group_by_path) 32 | 33 | 34 | # Function that extract entries matching a given regex from a list. 35 | # ${OUTPUT} will store the list of matching filenames. 36 | function(list_extract OUTPUT REGEX) 37 | 38 | foreach(FILENAME ${ARGN}) 39 | if(${FILENAME} MATCHES "${REGEX}") 40 | list(APPEND ${OUTPUT} ${FILENAME}) 41 | endif() 42 | endforeach() 43 | 44 | set(${OUTPUT} ${${OUTPUT}} PARENT_SCOPE) 45 | 46 | endfunction(list_extract) 47 | -------------------------------------------------------------------------------- /cmake/FindASSIMP.cmake: -------------------------------------------------------------------------------- 1 | 2 | # ASSIMP_FOUND 3 | # ASSIMP_INCLUDE_DIR 4 | # ASSIMP_LIBRARY_RELEASE 5 | # ASSIMP_LIBRARY_DEBUG 6 | # ASSIMP_LIBRARIES 7 | # ASSIMP_BINARY (win32 only) 8 | 9 | include(FindPackageHandleStandardArgs) 10 | 11 | find_path(ASSIMP_INCLUDE_DIR assimp/Importer.hpp 12 | 13 | PATHS 14 | $ENV{ASSIMP_DIR} 15 | $ENV{PROGRAMFILES}/Assimp 16 | /usr 17 | /usr/local 18 | /sw 19 | /opt/local 20 | 21 | PATH_SUFFIXES 22 | /include 23 | 24 | DOC "The directory where assimp/Importer.hpp etc. resides") 25 | 26 | if(MSVC AND X64) 27 | set(ASSIMP_PF "64") 28 | else() 29 | set(ASSIMP_PF "86") 30 | endif() 31 | 32 | find_library(ASSIMP_LIBRARY_RELEASE NAMES assimp 33 | 34 | HINTS 35 | ${ASSIMP_INCLUDE_DIR}/.. 36 | 37 | PATHS 38 | $ENV{ASSIMP_DIR} 39 | /usr 40 | /usr/local 41 | /sw 42 | /opt/local 43 | 44 | PATH_SUFFIXES 45 | /lib 46 | /lib${ASSIMP_PF} 47 | /build/code 48 | /build-debug/code 49 | 50 | DOC "The Assimp library (release)") 51 | 52 | find_library(ASSIMP_LIBRARY_DEBUG NAMES assimpd 53 | 54 | HINTS 55 | ${ASSIMP_INCLUDE_DIR}/.. 56 | 57 | PATHS 58 | $ENV{ASSIMP_DIR} 59 | /usr 60 | /usr/local 61 | /sw 62 | /opt/local 63 | 64 | PATH_SUFFIXES 65 | /lib 66 | /lib${ASSIMP_PF} 67 | /build/code 68 | /build-debug/code 69 | 70 | DOC "The Assimp library (debug)") 71 | 72 | set(ASSIMP_LIBRARIES "") 73 | if(ASSIMP_LIBRARY_RELEASE AND ASSIMP_LIBRARY_DEBUG) 74 | set(ASSIMP_LIBRARIES 75 | optimized ${ASSIMP_LIBRARY_RELEASE} 76 | debug ${ASSIMP_LIBRARY_DEBUG}) 77 | elseif(ASSIMP_LIBRARY_RELEASE) 78 | set(ASSIMP_LIBRARIES ${ASSIMP_LIBRARY_RELEASE}) 79 | elseif(ASSIMP_LIBRARY_DEBUG) 80 | set(ASSIMP_LIBRARIES ${ASSIMP_LIBRARY_DEBUG}) 81 | endif() 82 | 83 | if(WIN32) 84 | 85 | find_file(ASSIMP_BINARY NAMES assimp.dll "assimp${ASSIMP_PF}.dll" 86 | 87 | HINTS 88 | ${ASSIMP_INCLUDE_DIR}/.. 89 | 90 | PATHS 91 | $ENV{ASSIMP_DIR} 92 | 93 | PATH_SUFFIXES 94 | /bin 95 | /bin${ASSIMP_PF} 96 | 97 | DOC "The Assimp binary") 98 | 99 | endif() 100 | 101 | find_package_handle_standard_args(ASSIMP DEFAULT_MSG ASSIMP_LIBRARIES ASSIMP_INCLUDE_DIR) 102 | mark_as_advanced(ASSIMP_FOUND ASSIMP_INCLUDE_DIR ASSIMP_LIBRARIES) 103 | -------------------------------------------------------------------------------- /cmake/FindFFMPEG.cmake: -------------------------------------------------------------------------------- 1 | 2 | # - Try to find ffmpeg libraries (libavcodec, libavformat and libavutil) 3 | # Once done this will define 4 | # 5 | # FFMPEG_FOUND - system has ffmpeg or libav 6 | # FFMPEG_INCLUDE_DIR - the ffmpeg include directory 7 | # FFMPEG_LIBRARIES - Link these to use ffmpeg 8 | # FFMPEG_LIBAVCODEC 9 | # FFMPEG_LIBAVFORMAT 10 | # FFMPEG_LIBAVUTIL 11 | # FFMPEG_LIBSWSCALE 12 | # 13 | # Copyright (c) 2008 Andreas Schneider 14 | # Modified for other libraries by Lasse Kärkkäinen 15 | # Modified for Hedgewars by Stepik777 16 | # 17 | # Redistribution and use is allowed according to the terms of the New 18 | # BSD license. 19 | # 20 | 21 | if (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR) 22 | # in cache already 23 | set(FFMPEG_FOUND TRUE) 24 | else (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR) 25 | find_path(FFMPEG_AVCODEC_INCLUDE_DIR 26 | NAMES libavcodec/avcodec.h 27 | PATHS ${_FFMPEG_AVCODEC_INCLUDE_DIRS} /usr/include /usr/local/include /opt/local/include /sw/include 28 | PATH_SUFFIXES ffmpeg libav 29 | ) 30 | 31 | find_library(FFMPEG_LIBAVCODEC 32 | NAMES avcodec 33 | PATHS ${_FFMPEG_AVCODEC_LIBRARY_DIRS} /usr/lib /usr/local/lib /opt/local/lib /sw/lib 34 | ) 35 | 36 | find_library(FFMPEG_LIBAVFORMAT 37 | NAMES avformat 38 | PATHS ${_FFMPEG_AVFORMAT_LIBRARY_DIRS} /usr/lib /usr/local/lib /opt/local/lib /sw/lib 39 | ) 40 | 41 | find_library(FFMPEG_LIBAVUTIL 42 | NAMES avutil 43 | PATHS ${_FFMPEG_AVUTIL_LIBRARY_DIRS} /usr/lib /usr/local/lib /opt/local/lib /sw/lib 44 | ) 45 | 46 | find_library(FFMPEG_LIBSWSCALE 47 | NAMES swscale 48 | PATHS ${_FFMPEG_SWSCALE_LIBRARY_DIRS} /usr/lib /usr/local/lib /opt/local/lib /sw/lib 49 | ) 50 | 51 | if (FFMPEG_LIBAVCODEC AND FFMPEG_LIBAVFORMAT) 52 | set(FFMPEG_FOUND TRUE) 53 | endif() 54 | 55 | if (FFMPEG_FOUND) 56 | set(FFMPEG_INCLUDE_DIR ${FFMPEG_AVCODEC_INCLUDE_DIR}) 57 | 58 | set(FFMPEG_LIBRARIES 59 | ${FFMPEG_LIBAVCODEC} 60 | ${FFMPEG_LIBAVFORMAT} 61 | ${FFMPEG_LIBAVUTIL} 62 | ) 63 | 64 | endif (FFMPEG_FOUND) 65 | 66 | if (FFMPEG_FOUND) 67 | if (NOT FFMPEG_FIND_QUIETLY) 68 | message(STATUS "Found FFMPEG or Libav: ${FFMPEG_LIBRARIES}, ${FFMPEG_INCLUDE_DIR}") 69 | endif (NOT FFMPEG_FIND_QUIETLY) 70 | else (FFMPEG_FOUND) 71 | if (FFMPEG_FIND_REQUIRED) 72 | message(FATAL_ERROR "Could not find libavcodec or libavformat or libavutil") 73 | endif (FFMPEG_FIND_REQUIRED) 74 | endif (FFMPEG_FOUND) 75 | 76 | endif (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR) 77 | -------------------------------------------------------------------------------- /cmake/FindGLEW.cmake: -------------------------------------------------------------------------------- 1 | 2 | # GLEW_FOUND 3 | # GLEW_INCLUDE_DIR 4 | # GLEW_LIBRARY 5 | 6 | # GLEW_BINARY (win32 only) 7 | 8 | 9 | find_path(GLEW_INCLUDE_DIR GL/glew.h 10 | 11 | PATHS 12 | $ENV{GLEW_DIR} 13 | /usr 14 | /usr/local 15 | /sw 16 | /opt/local 17 | 18 | PATH_SUFFIXES 19 | /include 20 | 21 | DOC "The directory where GL/glew.h resides") 22 | 23 | if (X64) 24 | set(GLEW_BUILD_DIR Release/x64) 25 | else() 26 | set(GLEW_BUILD_DIR Release/Win32) 27 | endif() 28 | 29 | find_library(GLEW_LIBRARY NAMES GLEW glew glew32 glew32s 30 | 31 | PATHS 32 | $ENV{GLEW_DIR} 33 | /usr 34 | /usr/local 35 | /sw 36 | /opt/local 37 | 38 | # authors prefered choice for development 39 | /build 40 | /build-release 41 | /build-debug 42 | $ENV{GLEW_DIR}/build 43 | $ENV{GLEW_DIR}/build-release 44 | $ENV{GLEW_DIR}/build-debug 45 | 46 | PATH_SUFFIXES 47 | /lib 48 | /lib64 49 | /lib/${GLEW_BUILD_DIR} 50 | 51 | DOC "The GLEW library") 52 | 53 | if(WIN32) 54 | 55 | find_file(GLEW_BINARY NAMES glew32.dll glew32s.dll 56 | 57 | HINTS 58 | ${GLEW_INCLUDE_DIR}/.. 59 | 60 | PATHS 61 | $ENV{GLEW_DIR} 62 | 63 | PATH_SUFFIXES 64 | /bin 65 | /bin/${GLEW_BUILD_DIR} 66 | 67 | DOC "The GLEW binary") 68 | 69 | endif() 70 | 71 | find_package_handle_standard_args(GLEW REQUIRED_VARS GLEW_INCLUDE_DIR GLEW_LIBRARY) 72 | mark_as_advanced(GLEW_INCLUDE_DIR GLEW_LIBRARY) 73 | -------------------------------------------------------------------------------- /cmake/FindGLFW.cmake: -------------------------------------------------------------------------------- 1 | 2 | # GLFW_FOUND 3 | # GLFW_INCLUDE_DIR 4 | # GLFW_LIBRARY_RELEASE 5 | # GLFW_LIBRARY_DEBUG 6 | # GLFW_LIBRARIES 7 | # GLFW_BINARY (win32 only) 8 | 9 | include(FindPackageHandleStandardArgs) 10 | 11 | 12 | find_path(GLFW_INCLUDE_DIR GLFW/glfw3.h 13 | 14 | PATHS 15 | $ENV{GLFW_DIR} 16 | /usr 17 | /usr/local 18 | /usr/include/GL 19 | /sw 20 | /opt/local 21 | /opt/graphics/OpenGL 22 | /opt/graphics/OpenGL/contrib/libglfw 23 | 24 | PATH_SUFFIXES 25 | /include 26 | 27 | DOC "The directory where GLFW/glfw.h resides") 28 | 29 | 30 | set(GLFW_LIB_SUFFIX "") 31 | if(MSVC14) 32 | set(GLFW_LIB_SUFFIX "vc2015") 33 | elseif(MSVS12) 34 | set(GLFW_LIB_SUFFIX "vc2013") 35 | elseif(MSVC11) 36 | set(GLFW_LIB_SUFFIX "vc2012") 37 | elseif(MSVC10) 38 | set(GLFW_LIB_SUFFIX "vc2010") 39 | elseif(MINGW) 40 | if(X64) 41 | set(GLFW_LIB_SUFFIX "mingw-w64") 42 | else() 43 | set(GLFW_LIB_SUFFIX "mingw") 44 | endif() 45 | endif() 46 | 47 | set(GLFW_NAMES glfw3 glfw) 48 | set(GLFW_DEBUG_NAMES glfw3d glfwd) 49 | if(WIN32) 50 | option(GLFW_SHARED "Use shared GLFW library (DLL)" ON) 51 | if(GLFW_SHARED) 52 | set(GLFW_NAMES glfw3dll glfwdll) 53 | set(GLFW_DEBUG_NAMES glfw3ddll glfwddll) 54 | endif() 55 | endif() 56 | 57 | find_library(GLFW_LIBRARY_RELEASE NAMES ${GLFW_NAMES} 58 | 59 | HINTS 60 | ${GLFW_INCLUDE_DIR}/.. 61 | 62 | PATHS 63 | $ENV{GLFW_DIR} 64 | /lib/x64 65 | /lib/cocoa 66 | /usr 67 | /usr/local 68 | /sw 69 | /opt/local 70 | 71 | # authors prefered choice for development 72 | /build 73 | /build-release 74 | $ENV{GLFW_DIR}/build 75 | $ENV{GLFW_DIR}/build-release 76 | 77 | PATH_SUFFIXES 78 | /lib 79 | /lib64 80 | /lib-${GLFW_LIB_SUFFIX} 81 | /src # for from-source builds 82 | 83 | DOC "The GLFW library") 84 | 85 | find_library(GLFW_LIBRARY_DEBUG NAMES ${GLFW_DEBUG_NAMES} 86 | 87 | HINTS 88 | ${GLFW_INCLUDE_DIR}/.. 89 | 90 | PATHS 91 | $ENV{GLFW_DIR} 92 | /lib/x64 93 | /lib/cocoa 94 | /usr 95 | /usr/local 96 | /sw 97 | /opt/local 98 | 99 | # authors prefered choice for development 100 | /build 101 | /build-debug 102 | $ENV{GLFW_DIR}/build 103 | $ENV{GLFW_DIR}/build-debug 104 | 105 | PATH_SUFFIXES 106 | /lib 107 | /lib64 108 | /src # for from-source builds 109 | 110 | DOC "The GLFW library") 111 | 112 | set(GLFW_LIBRARIES "") 113 | if(GLFW_LIBRARY_RELEASE AND GLFW_LIBRARY_DEBUG) 114 | set(GLFW_LIBRARIES 115 | optimized ${GLFW_LIBRARY_RELEASE} 116 | debug ${GLFW_LIBRARY_DEBUG}) 117 | elseif(GLFW_LIBRARY_RELEASE) 118 | set(GLFW_LIBRARIES ${GLFW_LIBRARY_RELEASE}) 119 | elseif(GLFW_LIBRARY_DEBUG) 120 | set(GLFW_LIBRARIES ${GLFW_LIBRARY_DEBUG}) 121 | endif() 122 | 123 | if(WIN32 AND GLFW_SHARED) 124 | 125 | find_file(GLFW_BINARY glfw3.dll 126 | 127 | HINTS 128 | ${GLFW_INCLUDE_DIR}/.. 129 | 130 | PATHS 131 | $ENV{GLFW_DIR} 132 | /lib/x64 133 | /lib/cocoa 134 | 135 | PATH_SUFFIXES 136 | /lib 137 | /bin 138 | /lib-${GLFW_LIB_SUFFIX} 139 | 140 | DOC "The GLFW binary") 141 | 142 | endif() 143 | 144 | if(APPLE) 145 | set(GLFW_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX") 146 | set(GLFW_iokit_LIBRARY "-framework IOKit" CACHE STRING "IOKit framework for OSX") 147 | set(GLFW_corevideo_LIBRARY "-framework CoreVideo" CACHE STRING "CoreVideo framework for OSX") 148 | endif() 149 | 150 | # GLFW is required to link statically for now (no deploy specified) 151 | 152 | find_package_handle_standard_args(GLFW DEFAULT_MSG GLFW_LIBRARIES GLFW_INCLUDE_DIR) 153 | mark_as_advanced(GLFW_FOUND GLFW_INCLUDE_DIR GLFW_LIBRARIES) 154 | -------------------------------------------------------------------------------- /cmake/FindGLM.cmake: -------------------------------------------------------------------------------- 1 | 2 | # GLM_FOUND 3 | # GLM_INCLUDE_DIR 4 | 5 | include(FindPackageHandleStandardArgs) 6 | 7 | FIND_PATH(GLM_INCLUDE_DIR glm/glm.hpp 8 | 9 | PATHS 10 | $ENV{GLM_DIR} 11 | /usr 12 | /usr/local 13 | /sw 14 | /opt/local 15 | 16 | PATH_SUFFIXES 17 | /include 18 | 19 | DOC "The directory where glm/glm.hpp resides.") 20 | 21 | find_package_handle_standard_args(GLM REQUIRED_VARS GLM_INCLUDE_DIR) 22 | 23 | mark_as_advanced(GLM_INCLUDE_DIR) 24 | -------------------------------------------------------------------------------- /cmake/FindLibCrypto.cmake: -------------------------------------------------------------------------------- 1 | 2 | # LIBCRYPTO_LIBRARY 3 | 4 | include(FindPackageHandleStandardArgs) 5 | 6 | find_library(LIBCRYPTO_LIBRARY NAMES crypto) 7 | 8 | find_package_handle_standard_args(LibCrypto DEFAULT_MSG LIBCRYPTO_LIBRARY) 9 | mark_as_advanced(LIBCRYPTO_LIBRARY) 10 | -------------------------------------------------------------------------------- /cmake/FindLibSSH2.cmake: -------------------------------------------------------------------------------- 1 | 2 | # LIBSSH2_FOUND 3 | # LIBSSH2_INCLUDE_DIR 4 | # LIBSSH2_LIBRARY 5 | 6 | include(FindPackageHandleStandardArgs) 7 | 8 | find_path(LIBSSH2_INCLUDE_DIR libssh2.h) 9 | find_library(LIBSSH2_LIBRARY NAMES ssh2 libssh2 PATH_SUFFIXES /lib) 10 | 11 | find_package_handle_standard_args(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY) 12 | mark_as_advanced(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY) 13 | -------------------------------------------------------------------------------- /cmake/Findclang_tidy.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Findclang_tidy results: 3 | # clang_tidy_FOUND 4 | # clang_tidy_EXECUTABLE 5 | 6 | include(FindPackageHandleStandardArgs) 7 | 8 | find_program(clang_tidy_EXECUTABLE 9 | NAMES 10 | clang-tidy-3.5 11 | clang-tidy-3.6 12 | clang-tidy-3.7 13 | clang-tidy-3.8 14 | clang-tidy-3.9 15 | clang-tidy-4.0 16 | PATHS 17 | "${CLANG_TIDY_DIR}" 18 | ) 19 | 20 | find_package_handle_standard_args(clang_tidy 21 | FOUND_VAR 22 | clang_tidy_FOUND 23 | REQUIRED_VARS 24 | clang_tidy_EXECUTABLE 25 | ) 26 | 27 | mark_as_advanced(clang_tidy_EXECUTABLE) -------------------------------------------------------------------------------- /cmake/Findcppcheck.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Findcppcheck results: 3 | # cppcheck_FOUND 4 | # cppcheck_EXECUTABLE 5 | 6 | include(FindPackageHandleStandardArgs) 7 | 8 | find_program(cppcheck_EXECUTABLE 9 | NAMES 10 | cppcheck 11 | PATHS 12 | "${CPPCHECK_DIR}" 13 | ) 14 | 15 | find_package_handle_standard_args(cppcheck 16 | FOUND_VAR 17 | cppcheck_FOUND 18 | REQUIRED_VARS 19 | cppcheck_EXECUTABLE 20 | ) 21 | 22 | mark_as_advanced(cppcheck_EXECUTABLE) -------------------------------------------------------------------------------- /cmake/Findgoogletest.cmake: -------------------------------------------------------------------------------- 1 | 2 | # googletest_FOUND 3 | # Target googletest::googletest 4 | 5 | include(FindPackageHandleStandardArgs) 6 | 7 | find_package(PkgConfig) 8 | 9 | # enable MSVC syntax if required 10 | if("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") 11 | set(PKG_CONFIG_ARGN ${PKG_CONFIG_ARGN} "--msvc-syntax") 12 | endif() 13 | 14 | pkg_search_module(GMOCK QUIET gmock_main) 15 | 16 | find_package_handle_standard_args(googletest REQUIRED_VARS GMOCK_CFLAGS GMOCK_LDFLAGS) 17 | mark_as_advanced(GMOCK_CFLAGS GMOCK_LDFLAGS) 18 | 19 | if (googletest_FOUND) 20 | # the linker flags aren't correct for use with target_link_libraries 21 | # example: /libpath:[path]/lib.lib;gmock_main.lib;gmock.lib;gtest.lib 22 | # note that the path arg falsely includes a .lib suffix 23 | # additionally, cmake expects linker flags to start with - 24 | # thus, the leading / has to be replaced 25 | # example result: -libpath:[path]/lib;gmock_main.lib;gmock.lib;gtest.lib 26 | if("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") 27 | string(REGEX REPLACE "(\\/)(libpath[^;]*)(\\.lib)" "-\\2" GMOCK_LDFLAGS "${GMOCK_LDFLAGS}") 28 | endif() 29 | 30 | # Create interface library to link against gmock 31 | add_library(googletest::googletest INTERFACE IMPORTED) 32 | 33 | target_link_libraries(googletest::googletest 34 | INTERFACE 35 | ${GMOCK_LDFLAGS} 36 | ) 37 | 38 | target_compile_options(googletest::googletest 39 | INTERFACE 40 | ${GMOCK_CFLAGS} 41 | ) 42 | endif () 43 | -------------------------------------------------------------------------------- /cmake/Findnodejs.cmake: -------------------------------------------------------------------------------- 1 | 2 | # NODEJS_FOUND 3 | # NODEJS_INCLUDE_DIRS 4 | # NODEJS_INCLUDE_DIR 5 | # NODEJS_LIBUV_INCLUDE_DIR 6 | 7 | include(FindPackageHandleStandardArgs) 8 | 9 | find_path(NODEJS_INCLUDE_DIR node.h 10 | $ENV{NODEJS_HOME} 11 | $ENV{NODEJSDIR} 12 | $ENV{NODEJS_HOME}/src 13 | $ENV{NODEJSDIR}/src 14 | /usr/include/nodejs/src 15 | /usr/local/include/nodejs/src 16 | /usr/include 17 | /usr/local/include 18 | /sw/include 19 | /usr/local/include/node 20 | /opt/local/include 21 | DOC "The directory where node.h resides.") 22 | 23 | find_path(NODEJS_LIBUV_INCLUDE_DIR uv.h 24 | $ENV{NODEJS_HOME} 25 | $ENV{NODEJSDIR} 26 | $ENV{NODEJS_HOME}/src 27 | $ENV{NODEJSDIR}/src 28 | $ENV{NODEJS_HOME}/deps/uv/include 29 | $ENV{NODEJSDIR}/deps/uv/include 30 | /usr/include/nodejs/deps/uv/include 31 | /usr/local/include/nodejs/deps/uv/include 32 | /usr/include 33 | /usr/local/include 34 | /sw/include 35 | /opt/local/include 36 | /usr/local/include/node 37 | DOC "The directory where uv.h resides.") 38 | 39 | find_path(NODEJS_LIBV8_INCLUDE_DIR v8.h 40 | $ENV{NODEJS_HOME} 41 | $ENV{NODEJSDIR} 42 | $ENV{NODEJS_HOME}/src 43 | $ENV{NODEJSDIR}/src 44 | $ENV{NODEJS_HOME}/deps/v8/include 45 | $ENV{NODEJSDIR}/deps/v8/include 46 | /usr/include/nodejs/deps/uv/include 47 | /usr/local/include/nodejs/deps/uv/include 48 | /usr/include 49 | /usr/local/include 50 | /sw/include 51 | /opt/local/include 52 | /usr/local/include/node 53 | DOC "The directory where v8.h resides.") 54 | 55 | set(NODEJS_INCLUDE_DIRS ${NODEJS_INCLUDE_DIR} ${NODEJS_LIBUV_INCLUDE_DIR} ${NODEJS_LIBV8_INCLUDE_DIR}) 56 | 57 | find_package_handle_standard_args(NODEJS REQUIRED_VARS NODEJS_INCLUDE_DIRS) 58 | mark_as_advanced(NODEJS_INCLUDE_DIRS) 59 | -------------------------------------------------------------------------------- /cmake/GetGitRevisionDescription.cmake: -------------------------------------------------------------------------------- 1 | # - Returns a version string from Git 2 | # 3 | # These functions force a re-configure on each git commit so that you can 4 | # trust the values of the variables in your build system. 5 | # 6 | # get_git_head_revision( [ ...]) 7 | # 8 | # Returns the refspec and sha hash of the current head revision 9 | # 10 | # git_describe( [ ...]) 11 | # 12 | # Returns the results of git describe on the source tree, and adjusting 13 | # the output so that it tests false if an error occurs. 14 | # 15 | # git_get_exact_tag( [ ...]) 16 | # 17 | # Returns the results of git describe --exact-match on the source tree, 18 | # and adjusting the output so that it tests false if there was no exact 19 | # matching tag. 20 | # 21 | # Requires CMake 2.6 or newer (uses the 'function' command) 22 | # 23 | # Original Author: 24 | # 2009-2010 Ryan Pavlik 25 | # http://academic.cleardefinition.com 26 | # Iowa State University HCI Graduate Program/VRAC 27 | # 28 | # Copyright Iowa State University 2009-2010. 29 | # Distributed under the Boost Software License, Version 1.0. 30 | # (See accompanying file LICENSE_1_0.txt or copy at 31 | # http://www.boost.org/LICENSE_1_0.txt) 32 | 33 | if(__get_git_revision_description) 34 | return() 35 | endif() 36 | set(__get_git_revision_description YES) 37 | 38 | # We must run the following at "include" time, not at function call time, 39 | # to find the path to this module rather than the path to a calling list file 40 | get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) 41 | 42 | function(get_git_head_revision _refspecvar _hashvar) 43 | set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") 44 | set(GIT_DIR "${GIT_PARENT_DIR}/.git") 45 | while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories 46 | set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") 47 | get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) 48 | if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) 49 | # We have reached the root directory, we are not in git 50 | set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) 51 | set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) 52 | return() 53 | endif() 54 | set(GIT_DIR "${GIT_PARENT_DIR}/.git") 55 | endwhile() 56 | # check if this is a submodule 57 | if(NOT IS_DIRECTORY ${GIT_DIR}) 58 | file(READ ${GIT_DIR} submodule) 59 | string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) 60 | get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) 61 | get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) 62 | endif() 63 | set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") 64 | if(NOT EXISTS "${GIT_DATA}") 65 | file(MAKE_DIRECTORY "${GIT_DATA}") 66 | endif() 67 | 68 | if(NOT EXISTS "${GIT_DIR}/HEAD") 69 | return() 70 | endif() 71 | set(HEAD_FILE "${GIT_DATA}/HEAD") 72 | configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) 73 | 74 | configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" 75 | "${GIT_DATA}/grabRef.cmake" 76 | @ONLY) 77 | include("${GIT_DATA}/grabRef.cmake") 78 | 79 | set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) 80 | set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) 81 | endfunction() 82 | 83 | function(git_describe _var) 84 | if(NOT GIT_FOUND) 85 | find_package(Git QUIET) 86 | endif() 87 | get_git_head_revision(refspec hash) 88 | if(NOT GIT_FOUND) 89 | set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) 90 | return() 91 | endif() 92 | if(NOT hash) 93 | set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) 94 | return() 95 | endif() 96 | 97 | # TODO sanitize 98 | #if((${ARGN}" MATCHES "&&") OR 99 | # (ARGN MATCHES "||") OR 100 | # (ARGN MATCHES "\\;")) 101 | # message("Please report the following error to the project!") 102 | # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") 103 | #endif() 104 | 105 | #message(STATUS "Arguments to execute_process: ${ARGN}") 106 | 107 | execute_process(COMMAND 108 | "${GIT_EXECUTABLE}" 109 | describe 110 | ${hash} 111 | ${ARGN} 112 | WORKING_DIRECTORY 113 | "${CMAKE_CURRENT_SOURCE_DIR}" 114 | RESULT_VARIABLE 115 | res 116 | OUTPUT_VARIABLE 117 | out 118 | ERROR_QUIET 119 | OUTPUT_STRIP_TRAILING_WHITESPACE) 120 | if(NOT res EQUAL 0) 121 | set(out "${out}-${res}-NOTFOUND") 122 | endif() 123 | 124 | set(${_var} "${out}" PARENT_SCOPE) 125 | endfunction() 126 | 127 | function(git_get_exact_tag _var) 128 | git_describe(out --exact-match ${ARGN}) 129 | set(${_var} "${out}" PARENT_SCOPE) 130 | endfunction() 131 | -------------------------------------------------------------------------------- /cmake/GetGitRevisionDescription.cmake.in: -------------------------------------------------------------------------------- 1 | # 2 | # Internal file for GetGitRevisionDescription.cmake 3 | # 4 | # Requires CMake 2.6 or newer (uses the 'function' command) 5 | # 6 | # Original Author: 7 | # 2009-2010 Ryan Pavlik 8 | # http://academic.cleardefinition.com 9 | # Iowa State University HCI Graduate Program/VRAC 10 | # 11 | # Copyright Iowa State University 2009-2010. 12 | # Distributed under the Boost Software License, Version 1.0. 13 | # (See accompanying file LICENSE_1_0.txt or copy at 14 | # http://www.boost.org/LICENSE_1_0.txt) 15 | 16 | set(HEAD_HASH) 17 | 18 | file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) 19 | 20 | string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) 21 | if(HEAD_CONTENTS MATCHES "ref") 22 | # named branch 23 | string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") 24 | if(EXISTS "@GIT_DIR@/${HEAD_REF}") 25 | configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) 26 | else() 27 | configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) 28 | file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) 29 | if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") 30 | set(HEAD_HASH "${CMAKE_MATCH_1}") 31 | endif() 32 | endif() 33 | else() 34 | # detached HEAD 35 | configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) 36 | endif() 37 | 38 | if(NOT HEAD_HASH) 39 | file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) 40 | string(STRIP "${HEAD_HASH}" HEAD_HASH) 41 | endif() 42 | -------------------------------------------------------------------------------- /cmake/HealthCheck.cmake: -------------------------------------------------------------------------------- 1 | 2 | include(${CMAKE_CURRENT_LIST_DIR}/Cppcheck.cmake) 3 | include(${CMAKE_CURRENT_LIST_DIR}/ClangTidy.cmake) 4 | 5 | set(OPTION_CPPCHECK_ENABLED Off) 6 | set(OPTION_CLANG_TIDY_ENABLED Off) 7 | 8 | # Function to register a target for enabled health checks 9 | function(perform_health_checks target) 10 | if(NOT TARGET check-all) 11 | add_custom_target(check-all) 12 | endif() 13 | 14 | add_custom_target(check-${target}) 15 | 16 | if (OPTION_CPPCHECK_ENABLED) 17 | perform_cppcheck(cppcheck-${target} ${target} ${ARGN}) 18 | add_dependencies(check-${target} cppcheck-${target}) 19 | endif() 20 | 21 | if (OPTION_CLANG_TIDY_ENABLED) 22 | perform_clang_tidy(clang-tidy-${target} ${target} ${ARGN}) 23 | add_dependencies(check-${target} clang-tidy-${target}) 24 | endif() 25 | 26 | add_dependencies(check-all check-${target}) 27 | endfunction() 28 | 29 | # Enable or disable cppcheck for health checks 30 | function(enable_cppcheck status) 31 | if(NOT ${status}) 32 | set(OPTION_CPPCHECK_ENABLED ${status} PARENT_SCOPE) 33 | message(STATUS "Check cppcheck skipped: Manually disabled") 34 | 35 | return() 36 | endif() 37 | 38 | find_package(cppcheck) 39 | 40 | if(NOT cppcheck_FOUND) 41 | set(OPTION_CPPCHECK_ENABLED Off PARENT_SCOPE) 42 | message(STATUS "Check cppcheck skipped: cppcheck not found") 43 | 44 | return() 45 | endif() 46 | 47 | set(OPTION_CPPCHECK_ENABLED ${status} PARENT_SCOPE) 48 | message(STATUS "Check cppcheck") 49 | endfunction() 50 | 51 | # Enable or disable clang-tidy for health checks 52 | function(enable_clang_tidy status) 53 | if(NOT ${status}) 54 | set(OPTION_CLANG_TIDY_ENABLED ${status} PARENT_SCOPE) 55 | message(STATUS "Check clang-tidy skipped: Manually disabled") 56 | 57 | return() 58 | endif() 59 | 60 | find_package(clang_tidy) 61 | 62 | if(NOT clang_tidy_FOUND) 63 | set(OPTION_CLANG_TIDY_ENABLED Off PARENT_SCOPE) 64 | message(STATUS "Check clang-tidy skipped: clang-tidy not found") 65 | 66 | return() 67 | endif() 68 | 69 | set(OPTION_CLANG_TIDY_ENABLED ${status} PARENT_SCOPE) 70 | message(STATUS "Check clang-tidy") 71 | 72 | set(CMAKE_EXPORT_COMPILE_COMMANDS On PARENT_SCOPE) 73 | endfunction() 74 | -------------------------------------------------------------------------------- /cmake/RuntimeDependencies.cmake: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Default dependencies for the runtime-package 4 | # 5 | 6 | # Install 3rd-party runtime dependencies into runtime-component 7 | # install(FILES ... COMPONENT runtime) 8 | 9 | 10 | # 11 | # Full dependencies for self-contained packages 12 | # 13 | 14 | if(OPTION_SELF_CONTAINED) 15 | 16 | if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") 17 | 18 | # Install 3rd-party runtime dependencies into runtime-component 19 | # install(FILES ... COMPONENT runtime) 20 | 21 | find_file(DLLS_CPPASSIST cppassist.dll) 22 | 23 | set(DLLS 24 | ${DLLS_CPPASSIST} 25 | ) 26 | set(PLATFORMS 27 | ${DLLS_WIN} 28 | ) 29 | install(FILES ${DLLS} DESTINATION ${INSTALL_BIN} COMPONENT examples) 30 | install(FILES ${PLATFORMS} DESTINATION ${INSTALL_BIN}/platforms COMPONENT examples) 31 | 32 | endif() 33 | 34 | endif() 35 | -------------------------------------------------------------------------------- /cppfs-config.cmake: -------------------------------------------------------------------------------- 1 | 2 | # This config script tries to locate the project either in its source tree 3 | # or from an install location. 4 | # 5 | # Please adjust the list of submodules to search for. 6 | 7 | 8 | # List of modules 9 | set(MODULE_NAMES 10 | cppfs 11 | ) 12 | 13 | 14 | # Macro to search for a specific module 15 | macro(find_module FILENAME) 16 | if(EXISTS "${FILENAME}") 17 | set(MODULE_FOUND TRUE) 18 | include("${FILENAME}") 19 | endif() 20 | endmacro() 21 | 22 | # Macro to search for all modules 23 | macro(find_modules PREFIX) 24 | foreach(module_name ${MODULE_NAMES}) 25 | if(TARGET ${module_name}) 26 | set(MODULE_FOUND TRUE) 27 | else() 28 | find_module("${CMAKE_CURRENT_LIST_DIR}/${PREFIX}/${module_name}/${module_name}-export.cmake") 29 | endif() 30 | endforeach(module_name) 31 | endmacro() 32 | 33 | 34 | # Try install location 35 | set(MODULE_FOUND FALSE) 36 | find_modules("cmake") 37 | 38 | if(MODULE_FOUND) 39 | return() 40 | endif() 41 | 42 | # Try common build locations 43 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 44 | find_modules("build-debug/cmake") 45 | find_modules("build/cmake") 46 | else() 47 | find_modules("build/cmake") 48 | find_modules("build-debug/cmake") 49 | endif() 50 | 51 | # Signal success/failure to CMake 52 | set(cppfs_FOUND ${MODULE_FOUND}) 53 | -------------------------------------------------------------------------------- /cppfs-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cginternals/cppfs/948774623fc39f9380d44728a7e0e92bf5e17863/cppfs-logo.png -------------------------------------------------------------------------------- /cppfs-logo.svg: -------------------------------------------------------------------------------- 1 | cppfs-logo -------------------------------------------------------------------------------- /deploy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Target 'pack' 4 | # 5 | 6 | add_custom_target(pack) 7 | set_target_properties(pack PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1) 8 | 9 | 10 | # Install additional runtime dependencies 11 | include(${PROJECT_SOURCE_DIR}/cmake/RuntimeDependencies.cmake) 12 | 13 | 14 | # 15 | # Packages 16 | # 17 | 18 | include(packages/pack-cppfs.cmake) 19 | 20 | 21 | # 22 | # Target 'component_install' 23 | # 24 | 25 | add_custom_target( 26 | component_install 27 | COMMAND make preinstall 28 | COMMAND ${CMAKE_COMMAND} -P ${PROJECT_SOURCE_DIR}/cmake/ComponentInstall.cmake 29 | WORKING_DIRECTORY ${PROJECT_BINARY_DIR} 30 | ) 31 | -------------------------------------------------------------------------------- /deploy/ubuntu-ppa/debian/changelog: -------------------------------------------------------------------------------- 1 | libcppfs (1.0.0-0) unknown; urgency=low 2 | 3 | * Initial release. 4 | 5 | -- Willy Scheibel Tue, 26 Jan 2016 21:58:03 +0100 6 | -------------------------------------------------------------------------------- /deploy/ubuntu-ppa/debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /deploy/ubuntu-ppa/debian/control: -------------------------------------------------------------------------------- 1 | Source: libcppfs 2 | Section: misc 3 | Priority: optional 4 | Maintainer: Willy Scheibel 5 | Build-Depends: build-essential, cmake, zlib1g-dev, libssl-dev, libssh2-1-dev, libcppassist-dev, doxygen, graphviz 6 | Standards-Version: 3.8.0 7 | 8 | Package: libcppfs 9 | Architecture: any 10 | Depends: zlib1g, libssh2-1, libssl1.0.0, libcppassist 11 | Homepage: https://github.com/cginternals/cppfs 12 | Description: Cross-platform C++ file system library supporting multiple backends. 13 | 14 | Package: libcppfs-dev 15 | Architecture: any 16 | Depends: libcppfs, zlib1g-dev, libssl-dev, libssh2-1-dev, libcppassist-dev 17 | Homepage: https://github.com/cginternals/cppfs 18 | Description: Cross-platform C++ file system library supporting multiple backends. 19 | 20 | Package: libcppfs-docs 21 | Architecture: any 22 | Homepage: https://github.com/cginternals/cppfs 23 | Description: Cross-platform C++ file system library supporting multiple backends. 24 | 25 | Package: libcppfs-dbg 26 | Architecture: any 27 | Depends: libcppfs, libcppfs-dev 28 | Homepage: https://github.com/cginternals/cppfs 29 | Description: Cross-platform C++ file system library supporting multiple backends. 30 | 31 | Package: libcppfs-all 32 | Architecture: any 33 | Depends: libcppfs, libcppfs-dev, libcppfs-docs 34 | Homepage: https://github.com/cginternals/cppfs 35 | Description: Cross-platform C++ file system library supporting multiple backends. 36 | -------------------------------------------------------------------------------- /deploy/ubuntu-ppa/debian/copyright: -------------------------------------------------------------------------------- 1 | This package was debianised by Willy Scheibel on 2 | Tue, 26 Jan 2016 21:58:00 +0100 3 | 4 | It was downloaded from: 5 | 6 | https://github.com/cginternals/cppfs 7 | 8 | Upstream Author: 9 | 10 | CG Internals 11 | 12 | Copyright: 13 | 14 | Copyright (c) 2017-2018 CG Internals GmbH and Computer Graphics Systems Group at the Hasso-Plattner-Institute, Germany. 15 | 16 | License: 17 | 18 | This software is available to you under the terms of the MIT license, see "https://github.com/cginternals/cppfs/blob/master/LICENSE". 19 | -------------------------------------------------------------------------------- /deploy/ubuntu-ppa/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | BUILDDIR = build 4 | BUILDDEBUGDIR = build-debug 5 | 6 | # firstly called by launchpad 7 | clean: 8 | rm -rf $(BUILDDIR) 9 | rm -rf $(BUILDDEBUGDIR) 10 | 11 | # secondly called by launchpad 12 | build: build-arch 13 | 14 | build-arch: 15 | mkdir $(BUILDDIR) 16 | cd $(BUILDDIR);cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DOPTION_BUILD_TESTS=Off -DOPTION_BUILD_EXAMPLES=Off -DOPTION_BUILD_DOCS=On .. 17 | make -C $(BUILDDIR) 18 | mkdir $(BUILDDEBUGDIR) 19 | cd $(BUILDDEBUGDIR);cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/usr -DOPTION_BUILD_TESTS=Off -DOPTION_BUILD_EXAMPLES=Off -DOPTION_BUILD_DOCS=Off .. 20 | make -C $(BUILDDEBUGDIR) 21 | 22 | # thirdly called by launchpad 23 | binary: binary-arch 24 | 25 | binary-arch: libcppfs libcppfs-dev libcppfs-docs libcppfs-dbg libcppfs-all 26 | 27 | libcppfs: 28 | cd $(BUILDDIR); DESTDIR=../debian/tmp COMPONENT=runtime make component_install 29 | mkdir -p debian/tmp/DEBIAN 30 | dpkg-gencontrol -plibcppfs 31 | dpkg --build debian/tmp .. 32 | rm -rf debian/tmp 33 | 34 | libcppfs-dev: 35 | cd $(BUILDDIR); DESTDIR=../debian/tmp COMPONENT=dev make component_install 36 | mkdir -p debian/tmp/DEBIAN 37 | dpkg-gencontrol -plibcppfs-dev 38 | dpkg --build debian/tmp .. 39 | rm -rf debian/tmp 40 | 41 | libcppfs-docs: 42 | cd $(BUILDDIR); DESTDIR=../debian/tmp COMPONENT=docs make component_install 43 | mkdir -p debian/tmp/DEBIAN 44 | dpkg-gencontrol -plibcppfs-docs 45 | dpkg --build debian/tmp .. 46 | rm -rf debian/tmp 47 | 48 | libcppfs-dbg: 49 | cd $(BUILDDEBUGDIR); DESTDIR=../debian/tmp COMPONENT=runtime make component_install 50 | cd $(BUILDDEBUGDIR); DESTDIR=../debian/tmp COMPONENT=dev make component_install 51 | rm -rf debian/tmp/usr/include 52 | rm debian/tmp/usr/share/*/*-config.cmake 53 | rm debian/tmp/usr/share/*/AUTHORS 54 | rm debian/tmp/usr/share/*/LICENSE 55 | rm debian/tmp/usr/share/*/README.md 56 | rm debian/tmp/usr/share/*/VERSION 57 | rm debian/tmp/usr/share/*/cmake/*/*-export.cmake 58 | mkdir -p debian/tmp/DEBIAN 59 | dpkg-gencontrol -plibcppfs-dbg 60 | dpkg --build debian/tmp .. 61 | rm -rf debian/tmp 62 | 63 | libcppfs-all: 64 | mkdir -p debian/tmp/DEBIAN 65 | dpkg-gencontrol -plibcppfs-all 66 | dpkg --build debian/tmp .. 67 | rm -rf debian/tmp 68 | 69 | .PHONY: build build-arch binary binary-arch clean libcppfs libcppfs-dev libcppfs-docs libcppfs-dbg libcppfs-all 70 | -------------------------------------------------------------------------------- /deploy/ubuntu-ppa/debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /deploy/ubuntu-ppa/recipe.txt: -------------------------------------------------------------------------------- 1 | # git-build-recipe format 0.4 deb-version {debupstream}+{revno} 2 | lp:cppfs v1.0 3 | nest-part packaging lp:cppfs deploy/ubuntu-ppa/debian debian v1.0 4 | -------------------------------------------------------------------------------- /docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Target 'docs' 4 | # 5 | 6 | if(NOT OPTION_BUILD_DOCS) 7 | return() 8 | endif() 9 | 10 | add_custom_target(docs) 11 | 12 | 13 | # 14 | # Documentation 15 | # 16 | 17 | add_subdirectory(api-docs) 18 | -------------------------------------------------------------------------------- /docs/api-docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Find doxygen 4 | # 5 | 6 | find_package(Doxygen) 7 | if(NOT DOXYGEN_FOUND) 8 | message(STATUS "Disabled generation of doxygen documentation (missing doxygen).") 9 | return() 10 | endif() 11 | 12 | 13 | # 14 | # Target name 15 | # 16 | 17 | set(target api-docs) 18 | message(STATUS "Doc ${target}") 19 | 20 | 21 | # 22 | # Input file 23 | # 24 | 25 | set(doxyfile_in doxyfile.in) 26 | 27 | 28 | # 29 | # Create documentation 30 | # 31 | 32 | # Set project variables 33 | set(doxyfile "${CMAKE_CURRENT_BINARY_DIR}/doxyfile") 34 | set(doxyfile_directory "${CMAKE_CURRENT_BINARY_DIR}/html") 35 | set(doxyfile_html "${doxyfile_directory}/index.html") 36 | 37 | # Get filename and path of doxyfile 38 | get_filename_component(name ${doxyfile_in} NAME) 39 | get_filename_component(path ${doxyfile_in} PATH) 40 | if(NOT path) 41 | set(path ${CMAKE_CURRENT_SOURCE_DIR}) 42 | endif() 43 | 44 | # Configure doxyfile (if it is a real doxyfile already, it should simply copy the file) 45 | set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 46 | configure_file(${doxyfile_in} ${doxyfile}) 47 | 48 | # Invoke doxygen 49 | add_custom_command( 50 | OUTPUT ${doxyfile_html} 51 | DEPENDS ${doxyfile} ${META_PROJECT_NAME}::cppfs 52 | WORKING_DIRECTORY ${path} 53 | COMMAND ${CMAKE_COMMAND} -E copy_directory ${path} ${doxyfile_directory} # ToDO, configure doxygen to use source as is 54 | COMMAND ${DOXYGEN} \"${doxyfile}\" 55 | COMMENT "Creating doxygen documentation." 56 | ) 57 | 58 | # Declare target 59 | add_custom_target(${target} ALL DEPENDS ${doxyfile_html}) 60 | add_dependencies(docs ${target}) 61 | 62 | 63 | # 64 | # Deployment 65 | # 66 | 67 | install( 68 | DIRECTORY ${doxyfile_directory} 69 | DESTINATION ${INSTALL_DOC} 70 | COMPONENT docs 71 | ) 72 | -------------------------------------------------------------------------------- /source/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Configuration for all sub-projects 4 | # 5 | 6 | # Generate version-header 7 | configure_file(version.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/${META_PROJECT_NAME}/${META_PROJECT_NAME}-version.h) 8 | 9 | 10 | # 11 | # Sub-projects 12 | # 13 | 14 | # Libraries 15 | set(IDE_FOLDER "") 16 | add_subdirectory(cppfs) 17 | 18 | # Examples 19 | set(IDE_FOLDER "Examples") 20 | add_subdirectory(examples) 21 | 22 | # Tests 23 | if(OPTION_BUILD_TESTS AND NOT MINGW) 24 | set(IDE_FOLDER "Tests") 25 | add_subdirectory(tests) 26 | endif() 27 | 28 | 29 | # 30 | # Deployment 31 | # 32 | 33 | # Deploy generated headers 34 | install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/${META_PROJECT_NAME} DESTINATION include COMPONENT dev) 35 | 36 | 37 | # 38 | # Project Health 39 | # 40 | 41 | add_subdirectory(scripts) 42 | -------------------------------------------------------------------------------- /source/cppfs/3rdparty/basen/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012 Andrzej Zawadzki (azawadzki@gmail.com) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /source/cppfs/3rdparty/basen/README.md: -------------------------------------------------------------------------------- 1 | base-n provides encoding/decoding support for BaseX encoding schemes accessible through a standard STL-like iterator interface. Standard Base16, Base32, and Base64 are available out-of-the-box. Adding or modifying custom schemes is supported. 2 | 3 | # Usage overview # 4 | 5 | base-n is a small, single-header library which provides standard Base16, Base32, Base64, and custom Base-N encoding support. 6 | 7 | The main functionality is delivered by the following functions in `bn` namespace: 8 | ``` 9 | template 10 | void encode_b16(Iter1 start, Iter1 end, Iter2 out); 11 | 12 | 13 | template 14 | void encode_b32(Iter1 start, Iter1 end, Iter2 out); 15 | 16 | 17 | template 18 | void encode_b64(Iter1 start, Iter1 end, Iter2 out); 19 | 20 | 21 | template 22 | void decode_b16(Iter1 start, Iter1 end, Iter2 out); 23 | 24 | 25 | template 26 | void decode_b32(Iter1 start, Iter1 end, Iter2 out); 27 | 28 | 29 | template 30 | void decode_b64(Iter1 start, Iter1 end, Iter2 out); 31 | ``` 32 | 33 | In order to encode and decode data in `std::string` variable `in`, you can do the following: 34 | ``` 35 | bn::encode_b64(in.begin(), in.end(), back_inserter(encoded)); 36 | bn::decode_b64(encoded.begin(), encoded.end(), ostream_iterator(cout, "")); 37 | ``` 38 | 39 | Should you find yourself lacking some encoding scheme or the default character mapping rules are not good for your use case, you can easily provide your own encoder. For that, you need to define a struct type which will describe the new encoding. Sample below: 40 | ``` 41 | struct b8_custom 42 | { 43 | static size_t group_length() 44 | { 45 | return 3; 46 | } 47 | 48 | static char encode(int index) 49 | { 50 | const char* const dictionary = "01234567"; 51 | assert(index < strlen(dictionary)); 52 | return dictionary[index]; 53 | } 54 | 55 | static char decode(char c) 56 | { 57 | if (c >= '0' && c <= '7') { 58 | return c - '0'; 59 | } 60 | return -1; 61 | } 62 | }; 63 | ... 64 | string encoded; 65 | bn::impl::encode(in.begin(), in.end(), back_inserter(encoded)); 66 | bn::impl::decode(encoded.begin(), encoded.end(), ostream_iterator(cout, "")); 67 | ``` 68 | 69 | For a full working example, see `basen_example.cpp` file in `example` directory. 70 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/AbstractFileIteratorBackend.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | 11 | namespace cppfs 12 | { 13 | 14 | 15 | class AbstractFileSystem; 16 | 17 | 18 | /** 19 | * @brief 20 | * Interface for iterating on directories 21 | */ 22 | class CPPFS_API AbstractFileIteratorBackend 23 | { 24 | public: 25 | /** 26 | * @brief 27 | * Constructor 28 | */ 29 | AbstractFileIteratorBackend(); 30 | 31 | /** 32 | * @brief 33 | * Destructor 34 | */ 35 | virtual ~AbstractFileIteratorBackend(); 36 | 37 | /** 38 | * @brief 39 | * Create a copy of this iterator 40 | * 41 | * @return 42 | * File iterator 43 | */ 44 | virtual std::unique_ptr clone() const = 0; 45 | 46 | /** 47 | * @brief 48 | * Get file system 49 | * 50 | * @return 51 | * File system (must NOT be null) 52 | */ 53 | virtual AbstractFileSystem * fs() const = 0; 54 | 55 | /** 56 | * @brief 57 | * Check if iterator points to a valid item 58 | * 59 | * @return 60 | * 'true' if valid, else 'false' 61 | */ 62 | virtual bool valid() const = 0; 63 | 64 | /** 65 | * @brief 66 | * Get path in file system on which the iterator operates 67 | * 68 | * @return 69 | * Path 70 | */ 71 | virtual std::string path() const = 0; 72 | 73 | /** 74 | * @brief 75 | * Get current index of iterator in the directory 76 | * 77 | * @return 78 | * Index, -1 if invalid 79 | */ 80 | virtual int index() const = 0; 81 | 82 | /** 83 | * @brief 84 | * Get name of current directory item 85 | * 86 | * @return 87 | * File name 88 | */ 89 | virtual std::string name() const = 0; 90 | 91 | /** 92 | * @brief 93 | * Advance to the next item 94 | */ 95 | virtual void next() = 0; 96 | }; 97 | 98 | 99 | } // namespace cppfs 100 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/AbstractFileSystem.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | 11 | namespace cppfs 12 | { 13 | 14 | 15 | class FileHandle; 16 | class FileWatcher; 17 | class AbstractFileWatcherBackend; 18 | 19 | 20 | /** 21 | * @brief 22 | * Interface for accessing file systems 23 | */ 24 | class CPPFS_API AbstractFileSystem 25 | { 26 | public: 27 | /** 28 | * @brief 29 | * Constructor 30 | */ 31 | AbstractFileSystem(); 32 | 33 | /** 34 | * @brief 35 | * Destructor 36 | */ 37 | virtual ~AbstractFileSystem(); 38 | 39 | /** 40 | * @brief 41 | * Open file or directory in file system 42 | * 43 | * @param[in] path 44 | * Path to file or directory 45 | */ 46 | virtual FileHandle open(const std::string & path) = 0; 47 | 48 | /** 49 | * @brief 50 | * Open file or directory in file system 51 | * 52 | * @param[in] path 53 | * Path to file or directory 54 | */ 55 | virtual FileHandle open(std::string && path) = 0; 56 | 57 | /** 58 | * @brief 59 | * Create a watcher for the file system 60 | * 61 | * @param[in] fileWatcher 62 | * File watcher that owns the backend 63 | * 64 | * @return 65 | * Watcher backend (must NOT be null!) 66 | */ 67 | virtual std::unique_ptr createFileWatcher(FileWatcher & fileWatcher) = 0; 68 | }; 69 | 70 | 71 | } // namespace cppfs 72 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/AbstractFileWatcherBackend.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | class FileHandle; 15 | class FileWatcher; 16 | class AbstractFileSystem; 17 | 18 | 19 | /** 20 | * @brief 21 | * Interface for file watchers 22 | */ 23 | class CPPFS_API AbstractFileWatcherBackend 24 | { 25 | friend class FileWatcher; 26 | 27 | 28 | public: 29 | /** 30 | * @brief 31 | * Constructor 32 | * 33 | * @param[in] fileWatcher 34 | * File watcher that owns the backend (must NOT be null!) 35 | */ 36 | AbstractFileWatcherBackend(FileWatcher * fileWatcher); 37 | 38 | /** 39 | * @brief 40 | * Destructor 41 | */ 42 | virtual ~AbstractFileWatcherBackend(); 43 | 44 | /** 45 | * @brief 46 | * Get file system 47 | * 48 | * @return 49 | * File system (must NOT be null) 50 | */ 51 | virtual AbstractFileSystem * fs() const = 0; 52 | 53 | /** 54 | * @brief 55 | * Watch directory 56 | * 57 | * @param[in] dir 58 | * Handle to directory that shall be watched 59 | * @param[in] events 60 | * Events that are watched (combination of FileEvent values) 61 | * @param[in] recursive 62 | * Watch file system recursively? 63 | */ 64 | virtual void add(FileHandle & dir, unsigned int events, RecursiveMode recursive) = 0; 65 | 66 | /** 67 | * @brief 68 | * Start watching files 69 | * 70 | * @param[in] timeout 71 | * Timeout value in milliseconds. If less than zero, timeout is infinite and the function blocks. 72 | * 73 | * @remarks 74 | * This function shall watch the file system and block until one or more 75 | * events have occured, or if the timeout has been exceeded (timeout >= 0). 76 | * For each event, onFileEvent has to be called with the type of the event and 77 | * a file handle to the file or directory. After all events have been 78 | * processed, the function shall return. 79 | */ 80 | virtual void watch(int timeout) = 0; 81 | 82 | 83 | protected: 84 | /** 85 | * @brief 86 | * Called on each file event 87 | * 88 | * @param[in] fh 89 | * File handle 90 | * @param[in] event 91 | * Type of event that has occured 92 | */ 93 | void onFileEvent(FileHandle & fh, FileEvent event); 94 | 95 | 96 | protected: 97 | FileWatcher * m_fileWatcher; ///< File watcher that owns the backend (never null) 98 | }; 99 | 100 | 101 | } // namespace cppfs 102 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/Change.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | /** 15 | * @brief 16 | * Representation of one change to a directory tree 17 | */ 18 | class CPPFS_API Change 19 | { 20 | public: 21 | /** 22 | * @brief 23 | * Type of operation on the file system 24 | */ 25 | enum Operation 26 | { 27 | None = 0, ///< No operation 28 | CopyFile, ///< A file has been added or modified 29 | CopyDir, ///< A directory tree has been added 30 | RemoveFile, ///< A file has been removed 31 | RemoveDir ///< A directory tree has been removed 32 | }; 33 | 34 | 35 | public: 36 | /** 37 | * @brief 38 | * Constructor 39 | */ 40 | Change(); 41 | 42 | /** 43 | * @brief 44 | * Constructor 45 | * 46 | * @param[in] operation 47 | * Operation type 48 | * @param[in] path 49 | * Path on which the operation takes place 50 | */ 51 | Change(Operation operation, const std::string & path); 52 | 53 | /** 54 | * @brief 55 | * Constructor 56 | * 57 | * @param[in] operation 58 | * Operation type 59 | * @param[in] path 60 | * Path on which the operation takes place 61 | */ 62 | Change(Operation operation, std::string && path); 63 | 64 | /** 65 | * @brief 66 | * Copy constructor 67 | * 68 | * @param[in] change 69 | * Other change 70 | */ 71 | Change(const Change & change); 72 | 73 | /** 74 | * @brief 75 | * Move constructor 76 | * 77 | * @param[in] change 78 | * Other change 79 | */ 80 | Change(Change && change); 81 | 82 | /** 83 | * @brief 84 | * Destructor 85 | */ 86 | ~Change(); 87 | 88 | /** 89 | * @brief 90 | * Copy operator 91 | * 92 | * @param[in] change 93 | * Other change 94 | */ 95 | Change & operator=(const Change & change); 96 | 97 | /** 98 | * @brief 99 | * Move operator 100 | * 101 | * @param[in] change 102 | * Other change 103 | */ 104 | Change & operator=(Change && change); 105 | 106 | /** 107 | * @brief 108 | * Get string representation of the change 109 | * 110 | * @return 111 | * String representation of the change 112 | */ 113 | std::string toString() const; 114 | 115 | /** 116 | * @brief 117 | * Get operation 118 | * 119 | * @return 120 | * Operation type 121 | */ 122 | Operation operation() const; 123 | 124 | /** 125 | * @brief 126 | * Get path 127 | * 128 | * @return 129 | * Path on which the operation takes place 130 | */ 131 | const std::string & path() const; 132 | 133 | 134 | protected: 135 | Operation m_operation; ///< Operation type 136 | std::string m_path; ///< Path on which the operation takes place 137 | }; 138 | 139 | 140 | } // namespace cppfs 141 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/Diff.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | 11 | namespace cppfs 12 | { 13 | 14 | 15 | /** 16 | * @brief 17 | * Representation of changes to a directory tree 18 | */ 19 | class CPPFS_API Diff 20 | { 21 | public: 22 | /** 23 | * @brief 24 | * Constructor 25 | */ 26 | Diff(); 27 | 28 | /** 29 | * @brief 30 | * Destructor 31 | */ 32 | ~Diff(); 33 | 34 | /** 35 | * @brief 36 | * Clear data 37 | */ 38 | void clear(); 39 | 40 | /** 41 | * @brief 42 | * Get changes 43 | * 44 | * @return 45 | * List of changes 46 | */ 47 | const std::vector & changes() const; 48 | 49 | /** 50 | * @brief 51 | * Add change 52 | * 53 | * @param[in] change 54 | * Change 55 | */ 56 | void add(const Change & change); 57 | 58 | /** 59 | * @brief 60 | * Add change 61 | * 62 | * @param[in] change 63 | * Change 64 | */ 65 | void add(Change && change); 66 | 67 | /** 68 | * @brief 69 | * Add change 70 | * 71 | * @param[in] operation 72 | * Operation type 73 | * @param[in] path 74 | * Path on which the operation takes place 75 | */ 76 | void add(Change::Operation operation, const std::string & path); 77 | 78 | /** 79 | * @brief 80 | * Add change 81 | * 82 | * @param[in] operation 83 | * Operation type 84 | * @param[in] path 85 | * Path on which the operation takes place 86 | */ 87 | void add(Change::Operation operation, std::string && path); 88 | 89 | /** 90 | * @brief 91 | * Print changes to stream 92 | * 93 | * @param[in] stream 94 | * The output stream 95 | */ 96 | void print(std::ostream & stream); 97 | 98 | /** 99 | * @brief 100 | * Print changes to console 101 | */ 102 | void print(); 103 | 104 | 105 | protected: 106 | std::vector m_changes; ///< List of changes 107 | }; 108 | 109 | 110 | } // namespace cppfs 111 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/FileEventHandler.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | 8 | namespace cppfs 9 | { 10 | 11 | 12 | class FileHandle; 13 | 14 | 15 | /** 16 | * @brief 17 | * Handler that is informed about file system events 18 | * 19 | * @remarks 20 | * Use FileWatcher to register file event handlers. 21 | */ 22 | class CPPFS_API FileEventHandler 23 | { 24 | friend class FileWatcher; 25 | 26 | 27 | public: 28 | /** 29 | * @brief 30 | * Constructor 31 | */ 32 | FileEventHandler(); 33 | 34 | /** 35 | * @brief 36 | * Destructor 37 | */ 38 | virtual ~FileEventHandler(); 39 | 40 | 41 | protected: 42 | /** 43 | * @brief 44 | * Called on file event 45 | * 46 | * @param[in] fh 47 | * Handle to file or directory 48 | * @param[in] event 49 | * Type of event that has occured 50 | */ 51 | virtual void onFileEvent(FileHandle & fh, FileEvent event); 52 | 53 | /** 54 | * @brief 55 | * Called when a file or directory has been created 56 | * 57 | * @param[in] fh 58 | * Handle to file or directory 59 | */ 60 | virtual void onFileCreated(FileHandle & fh); 61 | 62 | /** 63 | * @brief 64 | * Called when a file or directory has been removed 65 | * 66 | * @param[in] fh 67 | * Handle to file or directory 68 | */ 69 | virtual void onFileRemoved(FileHandle & fh); 70 | 71 | /** 72 | * @brief 73 | * Called when a file or directory has been modified 74 | * 75 | * @param[in] fh 76 | * Handle to file or directory 77 | */ 78 | virtual void onFileModified(FileHandle & fh); 79 | 80 | /** 81 | * @brief 82 | * Called when file attributes have been modified 83 | * 84 | * @param[in] fh 85 | * Handle to file or directory 86 | */ 87 | virtual void onFileAttrChanged(FileHandle & fh); 88 | }; 89 | 90 | 91 | } // namespace cppfs 92 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/FileIterator.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | 11 | namespace cppfs 12 | { 13 | 14 | 15 | class AbstractFileSystem; 16 | class AbstractFileIteratorBackend; 17 | 18 | 19 | /** 20 | * @brief 21 | * File iterator 22 | */ 23 | class CPPFS_API FileIterator 24 | { 25 | public: 26 | /** 27 | * @brief 28 | * Constructor 29 | */ 30 | FileIterator(); 31 | 32 | /** 33 | * @brief 34 | * Constructor 35 | * 36 | * @param[in] backend 37 | * Concrete file iterator backend 38 | */ 39 | FileIterator(std::unique_ptr && backend); 40 | 41 | /** 42 | * @brief 43 | * Copy constructor 44 | * 45 | * @param[in] fileIterator 46 | * Source iterator 47 | */ 48 | FileIterator(const FileIterator & fileIterator); 49 | 50 | /** 51 | * @brief 52 | * Move constructor 53 | * 54 | * @param[in] fileIterator 55 | * Source iterator 56 | */ 57 | FileIterator(FileIterator && fileIterator); 58 | 59 | /** 60 | * @brief 61 | * Destructor 62 | */ 63 | virtual ~FileIterator(); 64 | 65 | /** 66 | * @brief 67 | * Copy operator 68 | * 69 | * @param[in] fileIterator 70 | * Source iterator 71 | */ 72 | FileIterator & operator=(const FileIterator & fileIterator); 73 | 74 | /** 75 | * @brief 76 | * Get name of current directory item 77 | * 78 | * @return 79 | * File name 80 | */ 81 | std::string operator*() const; 82 | 83 | /** 84 | * @brief 85 | * Advance to the next item 86 | */ 87 | void operator++(); 88 | 89 | /** 90 | * @brief 91 | * Compare two iterators 92 | * 93 | * @param[in] it 94 | * Iterator 95 | * 96 | * @return 97 | * 'true' if iterators are equal, else 'false' 98 | */ 99 | bool operator==(const FileIterator & it) const; 100 | 101 | /** 102 | * @brief 103 | * Compare two iterators 104 | * 105 | * @param[in] it 106 | * Iterator 107 | * 108 | * @return 109 | * 'true' if iterators are not equal, else 'false' 110 | */ 111 | bool operator!=(const FileIterator & it) const; 112 | 113 | /** 114 | * @brief 115 | * Get file system 116 | * 117 | * @return 118 | * File system (can be null) 119 | */ 120 | AbstractFileSystem * fs() const; 121 | 122 | 123 | protected: 124 | std::unique_ptr m_backend; 125 | }; 126 | 127 | 128 | } // namespace cppfs 129 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/FileVisitor.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | 8 | namespace cppfs 9 | { 10 | 11 | 12 | class FileHandle; 13 | 14 | 15 | /** 16 | * @brief 17 | * File visitor 18 | */ 19 | class CPPFS_API FileVisitor 20 | { 21 | friend class FileHandle; 22 | 23 | 24 | public: 25 | /** 26 | * @brief 27 | * Constructor 28 | */ 29 | FileVisitor(); 30 | 31 | /** 32 | * @brief 33 | * Destructor 34 | */ 35 | virtual ~FileVisitor(); 36 | 37 | 38 | protected: 39 | /** 40 | * @brief 41 | * Called on each file entry (files and directories) 42 | * 43 | * @param[in] fh 44 | * Handle to file or directory 45 | * 46 | * @remarks 47 | * The default implementation checks if the file handle 48 | * points to a file or a directory and calls onFile() 49 | * or onDirectory() respectively. 50 | * 51 | * @return 52 | * 'true' if subdirectory should be traversed, else 'false' 53 | */ 54 | virtual bool onFileEntry(FileHandle & fh); 55 | 56 | /** 57 | * @brief 58 | * Called on each file 59 | * 60 | * @param[in] fh 61 | * Handle to file 62 | * 63 | * @return 64 | * Irrelevant for files 65 | */ 66 | virtual bool onFile(FileHandle & fh); 67 | 68 | /** 69 | * @brief 70 | * Called on each directory 71 | * 72 | * @param[in] fh 73 | * Handle to directory 74 | * 75 | * @return 76 | * 'true' if subdirectory should be traversed, else 'false' 77 | */ 78 | virtual bool onDirectory(FileHandle & fh); 79 | }; 80 | 81 | 82 | } // namespace cppfs 83 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/FunctionalFileEventHandler.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | /** 15 | * @brief 16 | * File event handler that calls a function 17 | */ 18 | class CPPFS_API FunctionalFileEventHandler : public FileEventHandler 19 | { 20 | public: 21 | /** 22 | * @brief 23 | * Callback function for file system events 24 | */ 25 | using EventFunc = std::function; 26 | 27 | 28 | public: 29 | /** 30 | * @brief 31 | * Constructor 32 | */ 33 | FunctionalFileEventHandler(); 34 | 35 | /** 36 | * @brief 37 | * Constructor 38 | * 39 | * @param[in] funcFileEvent 40 | * Function that is call on each file system event 41 | */ 42 | FunctionalFileEventHandler(EventFunc funcFileEvent); 43 | 44 | /** 45 | * @brief 46 | * Destructor 47 | */ 48 | virtual ~FunctionalFileEventHandler(); 49 | 50 | 51 | protected: 52 | virtual void onFileEvent(FileHandle & fh, FileEvent event) override; 53 | 54 | 55 | protected: 56 | EventFunc m_funcFileEvent; 57 | }; 58 | 59 | 60 | } // namespace cppfs 61 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/FunctionalFileVisitor.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | /** 15 | * @brief 16 | * File visitor that calls a function 17 | */ 18 | class CPPFS_API FunctionalFileVisitor : public FileVisitor 19 | { 20 | public: 21 | using VisitFunc = std::function; 22 | 23 | 24 | public: 25 | /** 26 | * @brief 27 | * Constructor 28 | */ 29 | FunctionalFileVisitor(); 30 | 31 | /** 32 | * @brief 33 | * Constructor 34 | * 35 | * @param[in] funcFileEntry 36 | * Function that is call on each file entry (files and directories) 37 | */ 38 | FunctionalFileVisitor(VisitFunc funcFileEntry); 39 | 40 | /** 41 | * @brief 42 | * Constructor 43 | * 44 | * @param[in] funcFile 45 | * Function that is call on each file 46 | * @param[in] funcDirectory 47 | * Function that is call on each directory 48 | */ 49 | FunctionalFileVisitor(VisitFunc funcFile, VisitFunc funcDirectory); 50 | 51 | /** 52 | * @brief 53 | * Destructor 54 | */ 55 | virtual ~FunctionalFileVisitor(); 56 | 57 | 58 | protected: 59 | virtual bool onFileEntry(FileHandle & fh) override; 60 | virtual bool onFile(FileHandle & fh) override; 61 | virtual bool onDirectory(FileHandle & fh) override; 62 | 63 | 64 | protected: 65 | VisitFunc m_funcFileEntry; 66 | VisitFunc m_funcFile; 67 | VisitFunc m_funcDirectory; 68 | }; 69 | 70 | 71 | } // namespace cppfs 72 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/InputStream.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | /** 15 | * @brief 16 | * Input stream 17 | */ 18 | class CPPFS_API InputStream : public std::istream 19 | { 20 | public: 21 | /** 22 | * @brief 23 | * Constructor 24 | * 25 | * @param[in] sb 26 | * Stream buffer (must NOT be null!) 27 | * 28 | * @remarks 29 | * The input stream takes ownership over the stream buffer 30 | */ 31 | explicit InputStream(std::streambuf * sb); 32 | 33 | /** 34 | * @brief 35 | * Destructor 36 | */ 37 | virtual ~InputStream(); 38 | 39 | 40 | protected: 41 | std::streambuf * m_sb; ///< The associated stream buffer 42 | }; 43 | 44 | 45 | } // namespace cppfs 46 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/LoginCredentials.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | 11 | namespace cppfs 12 | { 13 | 14 | 15 | /** 16 | * @brief 17 | * Login credentials for accessing file systems (e.g., username, password, key files, etc.) 18 | * 19 | * This class is used to pass additional login credentials needed to acces file systems, 20 | * for example include username, password, port numbers, or paths to key files. 21 | * It can contain arbitrary key/value pairs that are defined and interpreted by 22 | * the respective file system implementations. See the documentation for a specific file 23 | * system implementation to learn what options it supports. 24 | */ 25 | class CPPFS_API LoginCredentials 26 | { 27 | public: 28 | /** 29 | * @brief 30 | * Constructor 31 | */ 32 | LoginCredentials(); 33 | 34 | /** 35 | * @brief 36 | * Copy constructor 37 | * 38 | * @param[in] loginCredentials 39 | * Right-hand value to copy 40 | */ 41 | LoginCredentials(const LoginCredentials & loginCredentials); 42 | 43 | /** 44 | * @brief 45 | * Move constructor 46 | * 47 | * @param[in] loginCredentials 48 | * Right-hand value to copy 49 | */ 50 | LoginCredentials(const LoginCredentials && loginCredentials); 51 | 52 | /** 53 | * @brief 54 | * Destructor 55 | */ 56 | virtual ~LoginCredentials(); 57 | 58 | /** 59 | * @brief 60 | * Copy assignment operator 61 | * 62 | * @param[in] loginCredentials 63 | * Right-hand value to copy 64 | * 65 | * @return 66 | * Reference to this value 67 | */ 68 | LoginCredentials & operator=(const LoginCredentials & loginCredentials); 69 | 70 | /** 71 | * @brief 72 | * Move assignment operator 73 | * 74 | * @param[in] loginCredentials 75 | * Right-hand value to move 76 | * 77 | * @return 78 | * Reference to this value 79 | */ 80 | LoginCredentials & operator=(LoginCredentials && loginCredentials); 81 | 82 | /** 83 | * @brief 84 | * Load login credentials from file 85 | * 86 | * @param[in] path 87 | * Path to file 88 | * 89 | * @return 90 | * 'true' on success, else 'false' 91 | */ 92 | bool load(const std::string & path); 93 | 94 | /** 95 | * @brief 96 | * Save login credentials to file 97 | * 98 | * @param[in] path 99 | * Path to file 100 | * 101 | * @return 102 | * 'true' on success, else 'false' 103 | */ 104 | bool save(const std::string & path) const; 105 | 106 | /** 107 | * @brief 108 | * Check if a value is set for a given key 109 | * 110 | * @param[in] key 111 | * Key 112 | * 113 | * @return 114 | * 'true' if a value for that key is set, else 'false' 115 | */ 116 | bool isSet(const std::string & key) const; 117 | 118 | /** 119 | * @brief 120 | * Get value for key 121 | * 122 | * @param[in] key 123 | * Key 124 | * 125 | * @return 126 | * Value for key, "" if key does not exist 127 | */ 128 | const std::string & value(const std::string & key) const; 129 | 130 | /** 131 | * @brief 132 | * Set value for key 133 | * 134 | * @param[in] key 135 | * Key 136 | * @param[in] value 137 | * Value for key 138 | */ 139 | void setValue(const std::string & key, const std::string & value); 140 | 141 | /** 142 | * @brief 143 | * Set value for key 144 | * 145 | * @param[in] key 146 | * Key 147 | * @param[in] value 148 | * Value for key 149 | */ 150 | void setValue(const std::string & key, std::string && value); 151 | 152 | 153 | protected: 154 | std::map m_values; ///< Key/value pairs 155 | }; 156 | 157 | 158 | } // namespace cppfs 159 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/OutputStream.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | /** 15 | * @brief 16 | * Output stream 17 | */ 18 | class CPPFS_API OutputStream : public std::ostream 19 | { 20 | public: 21 | /** 22 | * @brief 23 | * Constructor 24 | * 25 | * @param[in] sb 26 | * Stream buffer (must NOT be null!) 27 | * 28 | * @remarks 29 | * The output stream takes ownership over the stream buffer 30 | */ 31 | explicit OutputStream(std::streambuf * sb); 32 | 33 | /** 34 | * @brief 35 | * Destructor 36 | */ 37 | virtual ~OutputStream(); 38 | 39 | 40 | protected: 41 | std::streambuf * m_sb; ///< The associated stream buffer 42 | }; 43 | 44 | 45 | } // namespace cppfs 46 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/Url.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | /** 15 | * @brief 16 | * Url wrapper 17 | * 18 | * This class is a wrapper that enables limited parsing of URLs. 19 | */ 20 | class CPPFS_API Url 21 | { 22 | public: 23 | /** 24 | * @brief 25 | * Constructor 26 | */ 27 | Url(); 28 | 29 | /** 30 | * @brief 31 | * Copy constructor 32 | * 33 | * @param[in] url 34 | * Url to copy 35 | */ 36 | Url(const Url & url); 37 | 38 | /** 39 | * @brief 40 | * Move constructor 41 | * 42 | * @param[in] url 43 | * Url to move 44 | */ 45 | Url(Url && url); 46 | 47 | /** 48 | * @brief 49 | * Constructor 50 | * 51 | * @param[in] url 52 | * Url 53 | */ 54 | Url(const std::string & url); 55 | 56 | /** 57 | * @brief 58 | * Constructor 59 | * 60 | * @param[in] url 61 | * Url 62 | */ 63 | Url(std::string && url); 64 | 65 | /** 66 | * @brief 67 | * Constructor 68 | * 69 | * @param[in] url 70 | * Url 71 | */ 72 | Url(const char * url); 73 | 74 | /** 75 | * @brief 76 | * Destructor 77 | */ 78 | virtual ~Url(); 79 | 80 | /** 81 | * @brief 82 | * Copy assignment operator 83 | * 84 | * @param[in] url 85 | * Right-hand value to copy 86 | * 87 | * @return 88 | * Reference to this value 89 | */ 90 | Url & operator=(const Url & url); 91 | 92 | /** 93 | * @brief 94 | * Move assignment operator 95 | * 96 | * @param[in] url 97 | * Right-hand value to move 98 | * 99 | * @return 100 | * Reference to this value 101 | */ 102 | Url & operator=(Url && url); 103 | 104 | /** 105 | * @brief 106 | * Get url as string 107 | * 108 | * @return 109 | * Url 110 | */ 111 | const std::string & toString() const; 112 | 113 | /** 114 | * @brief 115 | * Get protocol 116 | * 117 | * @return 118 | * Protocol part (including "://") 119 | */ 120 | const std::string & protocol() const; 121 | 122 | /** 123 | * @brief 124 | * Get location 125 | * 126 | * @return 127 | * Location (everything after the protocol part) 128 | */ 129 | const std::string & location() const; 130 | 131 | /** 132 | * @brief 133 | * Get address 134 | * 135 | * @return 136 | * Address (including username, password, and hostname) 137 | */ 138 | const std::string & address() const; 139 | 140 | /** 141 | * @brief 142 | * Get path 143 | * 144 | * @return 145 | * Path (everything after the address) 146 | */ 147 | const std::string & path() const; 148 | 149 | /** 150 | * @brief 151 | * Get login 152 | * 153 | * @return 154 | * Login part (username and password) 155 | */ 156 | const std::string & login() const; 157 | 158 | /** 159 | * @brief 160 | * Get host 161 | * 162 | * @return 163 | * Host name 164 | */ 165 | const std::string & host() const; 166 | 167 | /** 168 | * @brief 169 | * Get user name 170 | * 171 | * @return 172 | * User name 173 | */ 174 | const std::string & username() const; 175 | 176 | /** 177 | * @brief 178 | * Get password 179 | * 180 | * @return 181 | * Password 182 | */ 183 | const std::string & password() const; 184 | 185 | 186 | protected: 187 | /** 188 | * @brief 189 | * Analyze url 190 | */ 191 | void analyze() const; 192 | 193 | 194 | protected: 195 | std::string m_url; ///< Url string 196 | mutable bool m_analyzed; ///< 'true' if Url has been analyzed, else 'false' 197 | mutable std::string m_protocol; ///< Protocol part (including "://") 198 | mutable std::string m_location; ///< Location (everything after the protocol part) 199 | mutable std::string m_address; ///< Address (including username, password, and hostname) 200 | mutable std::string m_path; ///< Path (everything after the address) 201 | mutable std::string m_login; ///< Login part (username and password) 202 | mutable std::string m_host; ///< Host name 203 | mutable std::string m_username; ///< User name 204 | mutable std::string m_password; ///< Password 205 | }; 206 | 207 | 208 | } // namespace cppfs 209 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/cppfs.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | 8 | namespace cppfs 9 | { 10 | 11 | 12 | /** 13 | * @brief 14 | * File permission flags 15 | */ 16 | enum FilePermissions 17 | { 18 | UserRead = 0x400, 19 | UserWrite = 0x200, 20 | UserExec = 0x100, 21 | GroupRead = 0x040, 22 | GroupWrite = 0x020, 23 | GroupExec = 0x010, 24 | OtherRead = 0x004, 25 | OtherWrite = 0x002, 26 | OtherExec = 0x001, 27 | SetUid = 04000, 28 | SetGid = 02000, 29 | Sticky = 01000 30 | }; 31 | 32 | /** 33 | * @brief 34 | * Type of event on the file system 35 | */ 36 | enum FileEvent 37 | { 38 | FileCreated = 0x01, ///< A file or directory has been created 39 | FileRemoved = 0x02, ///< A file or directory has been removed 40 | FileModified = 0x04, ///< A file or directory has been modified 41 | FileAttrChanged = 0x08 ///< Attributes on a file or directory have been modified 42 | }; 43 | 44 | /** 45 | * @brief 46 | * Recursive mode for operation that can run recursively or non-recursively 47 | */ 48 | enum RecursiveMode 49 | { 50 | NonRecursive = 0, ///< Run recursively 51 | Recursive ///< Run non-recursively 52 | }; 53 | 54 | 55 | } // namespace cppfs 56 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/fs.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | 11 | namespace cppfs 12 | { 13 | 14 | 15 | class FileHandle; 16 | class LoginCredentials; 17 | 18 | 19 | /** 20 | * @brief 21 | * Global file system functions 22 | */ 23 | namespace fs 24 | { 25 | 26 | 27 | /** 28 | * @brief 29 | * Get local file system 30 | * 31 | * @return 32 | * Pointer to local file system (never null) 33 | */ 34 | CPPFS_API std::shared_ptr localFS(); 35 | 36 | /** 37 | * @brief 38 | * Open a file or directory 39 | * 40 | * @param[in] path 41 | * Path to file or directory 42 | * @param[in] credentials 43 | * Optional login credentials (can be null) 44 | * 45 | * @return 46 | * File handle 47 | */ 48 | CPPFS_API FileHandle open(const std::string & path, const LoginCredentials * credentials = nullptr); 49 | 50 | /** 51 | * @brief 52 | * Compute sha1 hash for string 53 | * 54 | * @param[in] str 55 | * String 56 | * 57 | * @return 58 | * SHA1 hash 59 | */ 60 | CPPFS_API std::string sha1(const std::string & str); 61 | 62 | /** 63 | * @brief 64 | * Get base64 encoding for string 65 | * 66 | * @param[in] str 67 | * String 68 | * 69 | * @return 70 | * Base64 encoded string 71 | */ 72 | CPPFS_API std::string base64(const std::string & str); 73 | 74 | /** 75 | * @brief 76 | * Get decoded string from base64 encoding 77 | * 78 | * @param[in] base64 79 | * Base64 encoded string 80 | * 81 | * @return 82 | * Decoded string 83 | */ 84 | CPPFS_API std::string fromBase64(const std::string & base64); 85 | 86 | /** 87 | * @brief 88 | * Convert hash buffer into string 89 | * 90 | * @param[in] hash 91 | * Hash buffer 92 | * 93 | * @return 94 | * Hash string 95 | */ 96 | CPPFS_API std::string hashToString(const unsigned char * hash); 97 | 98 | 99 | } // namespace fs 100 | 101 | 102 | } // namespace cppfs 103 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/linux/LocalFileWatcher.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | 12 | namespace cppfs 13 | { 14 | 15 | 16 | class LocalFileSystem; 17 | 18 | 19 | /** 20 | * @brief 21 | * File watcher for the local file system 22 | */ 23 | class CPPFS_API LocalFileWatcher : public AbstractFileWatcherBackend 24 | { 25 | public: 26 | /** 27 | * @brief 28 | * Constructor 29 | * 30 | * @param[in] fileWatcher 31 | * File watcher that owns the backend (must NOT be null!) 32 | * @param[in] fs 33 | * File system that created this watcher 34 | */ 35 | LocalFileWatcher(FileWatcher * fileWatcher, std::shared_ptr fs); 36 | 37 | /** 38 | * @brief 39 | * Destructor 40 | */ 41 | virtual ~LocalFileWatcher(); 42 | 43 | // Virtual AbstractFileWatcherBackend functions 44 | virtual AbstractFileSystem * fs() const override; 45 | virtual void add(FileHandle & dir, unsigned int events, RecursiveMode recursive) override; 46 | virtual void watch(int timeout) override; 47 | 48 | 49 | protected: 50 | /** 51 | * @brief 52 | * Watcher entry 53 | */ 54 | struct Watcher { 55 | FileHandle dir; 56 | unsigned int events; 57 | RecursiveMode recursive; 58 | }; 59 | 60 | 61 | protected: 62 | std::shared_ptr m_fs; ///< File system that created this watcher 63 | int m_inotify; ///< File handle for the inotify instance 64 | std::map m_watchers; ///< Map of watch handle -> file handle 65 | }; 66 | 67 | 68 | } // namespace cppfs 69 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/posix/LocalFileHandle.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | class LocalFileSystem; 15 | 16 | 17 | /** 18 | * @brief 19 | * File handle for the local file system 20 | */ 21 | class CPPFS_API LocalFileHandle : public AbstractFileHandleBackend 22 | { 23 | public: 24 | /** 25 | * @brief 26 | * Constructor 27 | * 28 | * @param[in] fs 29 | * File system that created this handle 30 | * @param[in] path 31 | * Path to file or directory 32 | */ 33 | LocalFileHandle(std::shared_ptr fs, const std::string & path); 34 | 35 | /** 36 | * @brief 37 | * Constructor 38 | * 39 | * @param[in] fs 40 | * File system that created this handle 41 | * @param[in] path 42 | * Path to file or directory 43 | */ 44 | LocalFileHandle(std::shared_ptr fs, std::string && path); 45 | 46 | /** 47 | * @brief 48 | * Destructor 49 | */ 50 | virtual ~LocalFileHandle(); 51 | 52 | // Virtual AbstractFileHandleBackend functions 53 | virtual std::unique_ptr clone() const override; 54 | virtual AbstractFileSystem * fs() const override; 55 | virtual void updateFileInfo() override; 56 | virtual std::string path() const override; 57 | virtual bool exists() const override; 58 | virtual bool isFile() const override; 59 | virtual bool isDirectory() const override; 60 | virtual bool isSymbolicLink() const override; 61 | virtual std::vector listFiles() const override; 62 | virtual std::unique_ptr begin() const override; 63 | virtual unsigned int size() const override; 64 | virtual unsigned int accessTime() const override; 65 | virtual unsigned int modificationTime() const override; 66 | virtual unsigned int userId() const override; 67 | virtual void setUserId(unsigned int uid) override; 68 | virtual unsigned int groupId() const override; 69 | virtual void setGroupId(unsigned int gid) override; 70 | virtual unsigned long permissions() const override; 71 | virtual void setPermissions(unsigned long permissions) override; 72 | virtual bool createDirectory() override; 73 | virtual bool removeDirectory() override; 74 | virtual bool copy(AbstractFileHandleBackend & dest) override; 75 | virtual bool move(AbstractFileHandleBackend & dest) override; 76 | virtual bool createLink(AbstractFileHandleBackend & dest) override; 77 | virtual bool createSymbolicLink(AbstractFileHandleBackend & dest) override; 78 | virtual bool rename(const std::string & filename) override; 79 | virtual bool remove() override; 80 | virtual std::unique_ptr createInputStream(std::ios_base::openmode mode) const override; 81 | virtual std::unique_ptr createOutputStream(std::ios_base::openmode mode) override; 82 | 83 | 84 | protected: 85 | void readFileInfo() const; 86 | void readLinkInfo() const; 87 | 88 | 89 | protected: 90 | std::shared_ptr m_fs; ///< File system that created this handle 91 | std::string m_path; ///< Path to file or directory 92 | mutable void * m_fileInfo; ///< Information about the current file (resolves links, created on demand) 93 | mutable void * m_linkInfo; ///< Information about the current file (does not resolve links, created on demand) 94 | }; 95 | 96 | 97 | } // namespace cppfs 98 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/posix/LocalFileIterator.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | 12 | namespace cppfs 13 | { 14 | 15 | 16 | class LocalFileSystem; 17 | 18 | 19 | /** 20 | * @brief 21 | * File iterator for the local file system 22 | */ 23 | class CPPFS_API LocalFileIterator : public AbstractFileIteratorBackend 24 | { 25 | public: 26 | /** 27 | * @brief 28 | * Constructor 29 | * 30 | * @param[in] fs 31 | * File system that created this iterator 32 | * @param[in] path 33 | * Path to file or directory 34 | */ 35 | LocalFileIterator(std::shared_ptr fs, const std::string & path); 36 | 37 | /** 38 | * @brief 39 | * Constructor 40 | * 41 | * @param[in] fs 42 | * File system that created this iterator 43 | * @param[in] path 44 | * Path to file or directory 45 | */ 46 | LocalFileIterator(std::shared_ptr fs, std::string && path); 47 | 48 | /** 49 | * @brief 50 | * Destructor 51 | */ 52 | virtual ~LocalFileIterator(); 53 | 54 | // Virtual AbstractFileIteratorBackend functions 55 | virtual std::unique_ptr clone() const override; 56 | virtual AbstractFileSystem * fs() const override; 57 | virtual bool valid() const override; 58 | virtual std::string path() const override; 59 | virtual int index() const override; 60 | virtual std::string name() const override; 61 | virtual void next() override; 62 | 63 | 64 | protected: 65 | void readNextEntry(); 66 | 67 | 68 | protected: 69 | std::shared_ptr m_fs; ///< File system that created this iterator 70 | std::string m_path; ///< Path to file or directory 71 | DIR * m_dir; ///< Directory handle 72 | struct dirent * m_entry; ///< Current directory entry 73 | int m_index; ///< Index of the current entry 74 | }; 75 | 76 | 77 | } // namespace cppfs 78 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/posix/LocalFileSystem.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | /** 15 | * @brief 16 | * Representation of the local file system 17 | */ 18 | class CPPFS_API LocalFileSystem : public AbstractFileSystem, public std::enable_shared_from_this 19 | { 20 | public: 21 | /** 22 | * @brief 23 | * Constructor 24 | */ 25 | LocalFileSystem(); 26 | 27 | /** 28 | * @brief 29 | * Destructor 30 | */ 31 | virtual ~LocalFileSystem(); 32 | 33 | // Virtual AbstractFileSystem functions 34 | virtual FileHandle open(const std::string & path) override; 35 | virtual FileHandle open(std::string && path) override; 36 | virtual std::unique_ptr createFileWatcher(FileWatcher & fileWatcher) override; 37 | }; 38 | 39 | 40 | } // namespace cppfs 41 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/ssh/SshFileHandle.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | class SshFileSystem; 15 | 16 | 17 | /** 18 | * @brief 19 | * File handle for a remote file system accessed by SSH 20 | */ 21 | class CPPFS_API SshFileHandle : public AbstractFileHandleBackend 22 | { 23 | public: 24 | /** 25 | * @brief 26 | * Constructor 27 | * 28 | * @param[in] fs 29 | * File system that created this handle 30 | * @param[in] path 31 | * Path to file or directory 32 | */ 33 | SshFileHandle(std::shared_ptr fs, const std::string & path); 34 | 35 | /** 36 | * @brief 37 | * Destructor 38 | */ 39 | virtual ~SshFileHandle(); 40 | 41 | // Virtual AbstractFileHandleBackend functions 42 | virtual std::unique_ptr clone() const override; 43 | virtual AbstractFileSystem * fs() const override; 44 | virtual void updateFileInfo() override; 45 | virtual std::string path() const override; 46 | virtual bool exists() const override; 47 | virtual bool isFile() const override; 48 | virtual bool isDirectory() const override; 49 | virtual bool isSymbolicLink() const override; 50 | virtual std::vector listFiles() const override; 51 | virtual std::unique_ptr begin() const override; 52 | virtual unsigned int size() const override; 53 | virtual unsigned int accessTime() const override; 54 | virtual unsigned int modificationTime() const override; 55 | virtual unsigned int userId() const override; 56 | virtual void setUserId(unsigned int uid) override; 57 | virtual unsigned int groupId() const override; 58 | virtual void setGroupId(unsigned int gid) override; 59 | virtual unsigned long permissions() const override; 60 | virtual void setPermissions(unsigned long permissions) override; 61 | virtual bool createDirectory() override; 62 | virtual bool removeDirectory() override; 63 | virtual bool copy(AbstractFileHandleBackend & dest) override; 64 | virtual bool move(AbstractFileHandleBackend & dest) override; 65 | virtual bool createLink(AbstractFileHandleBackend & dest) override; 66 | virtual bool createSymbolicLink(AbstractFileHandleBackend & dest) override; 67 | virtual bool rename(const std::string & filename) override; 68 | virtual bool remove() override; 69 | virtual std::unique_ptr createInputStream(std::ios_base::openmode mode) const override; 70 | virtual std::unique_ptr createOutputStream(std::ios_base::openmode mode) override; 71 | 72 | 73 | protected: 74 | void readFileInfo() const; 75 | void readLinkInfo() const; 76 | 77 | 78 | protected: 79 | std::shared_ptr m_fs; ///< File system that created this handle 80 | std::string m_path; ///< Path to file or directory 81 | mutable void * m_fileInfo; ///< Information about the current file (resolves links, created on demand) 82 | mutable void * m_linkInfo; ///< Information about the current file (does not resolve links, created on demand) 83 | }; 84 | 85 | 86 | } // namespace cppfs 87 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/ssh/SshFileIterator.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | 12 | namespace cppfs 13 | { 14 | 15 | 16 | class SshFileSystem; 17 | 18 | 19 | /** 20 | * @brief 21 | * File iterator for a remove file system accessed by SSH 22 | */ 23 | class CPPFS_API SshFileIterator : public AbstractFileIteratorBackend 24 | { 25 | public: 26 | /** 27 | * @brief 28 | * Constructor 29 | * 30 | * @param[in] fs 31 | * File system that created this iterator 32 | * @param[in] path 33 | * Path to file or directory 34 | */ 35 | SshFileIterator(std::shared_ptr fs, const std::string & path); 36 | 37 | /** 38 | * @brief 39 | * Destructor 40 | */ 41 | virtual ~SshFileIterator(); 42 | 43 | // Virtual AbstractFileIteratorBackend functions 44 | virtual std::unique_ptr clone() const override; 45 | virtual AbstractFileSystem * fs() const override; 46 | virtual bool valid() const override; 47 | virtual std::string path() const override; 48 | virtual int index() const override; 49 | virtual std::string name() const override; 50 | virtual void next() override; 51 | 52 | 53 | protected: 54 | void readNextEntry(); 55 | 56 | 57 | protected: 58 | std::shared_ptr m_fs; ///< File system that created this iterator 59 | std::string m_path; ///< Path to file or directory 60 | LIBSSH2_SFTP_HANDLE * m_dir; ///< Directory handle 61 | int m_index; ///< Current entry index 62 | std::string m_filename; ///< Current entry file name 63 | LIBSSH2_SFTP_ATTRIBUTES m_attrs; ///< Current entry attributes 64 | }; 65 | 66 | 67 | } // namespace cppfs 68 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/ssh/SshFileSystem.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | 11 | namespace cppfs 12 | { 13 | 14 | 15 | /** 16 | * @brief 17 | * Representation of a remote file system accessed by SSH 18 | */ 19 | class CPPFS_API SshFileSystem : public AbstractFileSystem, public std::enable_shared_from_this 20 | { 21 | friend class SshFileHandle; 22 | friend class SshFileIterator; 23 | friend class SshInputStreamBuffer; 24 | friend class SshOutputStreamBuffer; 25 | 26 | 27 | public: 28 | /** 29 | * @brief 30 | * Constructor 31 | * 32 | * @param[in] host 33 | * Host name 34 | * @param[in] port 35 | * Port 36 | * @param[in] username 37 | * User name 38 | * @param[in] password 39 | * Password 40 | * @param[in] publicKey 41 | * Path to public key file 42 | * @param[in] privateKey 43 | * Path to private key file 44 | */ 45 | SshFileSystem( 46 | const std::string & host, 47 | int port, 48 | const std::string & username, 49 | const std::string & password, 50 | const std::string & publicKey, 51 | const std::string & privateKey 52 | ); 53 | 54 | /** 55 | * @brief 56 | * Constructor 57 | * 58 | * @param[in] host 59 | * Host name 60 | * @param[in] port 61 | * Port 62 | * @param[in] username 63 | * User name 64 | * @param[in] password 65 | * Password 66 | * @param[in] publicKey 67 | * Path to public key file 68 | * @param[in] privateKey 69 | * Path to private key file 70 | */ 71 | SshFileSystem( 72 | std::string && host, 73 | int port, 74 | std::string && username, 75 | std::string && password, 76 | std::string && publicKey, 77 | std::string && privateKey 78 | ); 79 | 80 | /** 81 | * @brief 82 | * Destructor 83 | */ 84 | virtual ~SshFileSystem(); 85 | 86 | // Virtual AbstractFileSystem functions 87 | virtual FileHandle open(const std::string & path) override; 88 | virtual FileHandle open(std::string && path) override; 89 | virtual std::unique_ptr createFileWatcher(FileWatcher & fileWatcher) override; 90 | 91 | 92 | protected: 93 | void connect(); 94 | void disconnect(); 95 | void initSftp(); 96 | void checkError(); 97 | 98 | 99 | protected: 100 | // Configuration 101 | std::string m_host; 102 | int m_port; 103 | std::string m_username; 104 | std::string m_password; 105 | std::string m_publicKey; 106 | std::string m_privateKey; 107 | 108 | // Connection 109 | int m_socket; ///< Socket to host 110 | void * m_session; ///< SSH session handle 111 | void * m_sftpSession; ///< SFTP session handle 112 | }; 113 | 114 | 115 | } // namespace cppfs 116 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/ssh/SshInputStreamBuffer.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | 14 | namespace cppfs 15 | { 16 | 17 | 18 | class SshFileSystem; 19 | 20 | 21 | /** 22 | * @brief 23 | * Stream buffer for reading a SSH file 24 | */ 25 | class CPPFS_API SshInputStreamBuffer : public std::streambuf 26 | { 27 | public: 28 | /** 29 | * @brief 30 | * Constructor 31 | * 32 | * @param[in] fs 33 | * File system that created this iterator 34 | * @param[in] path 35 | * Path to file or directory 36 | * @param[in] mode 37 | * Opening mode flags 38 | * @param[n] bufferSize 39 | * Size of the read buffer 40 | * @param[n] putbackSize 41 | * Size of the putback area 42 | */ 43 | SshInputStreamBuffer(std::shared_ptr fs, const std::string & path, std::ios_base::openmode mode, size_t bufferSize = size_kb(32), size_t putBackSize = size_b(128)); 44 | 45 | /** 46 | * @brief 47 | * Destructor 48 | */ 49 | virtual ~SshInputStreamBuffer(); 50 | 51 | // Virtual streambuf functions 52 | virtual std::streambuf::int_type underflow() override; 53 | virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which) override; 54 | virtual pos_type seekpos(pos_type pos, std::ios_base::openmode which) override; 55 | 56 | 57 | protected: 58 | std::shared_ptr m_fs; ///< File system that created this iterator 59 | const std::string m_path; ///< Path to file or directory 60 | void * m_file; ///< SFTP file handle 61 | const size_t m_putbackSize; ///< Size of the putback area 62 | std::vector m_buffer; ///< Read buffer 63 | }; 64 | 65 | 66 | } // namespace cppfs 67 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/ssh/SshOutputStreamBuffer.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | 14 | namespace cppfs 15 | { 16 | 17 | 18 | class SshFileSystem; 19 | 20 | 21 | /** 22 | * @brief 23 | * Stream buffer for writing a SSH file 24 | */ 25 | class CPPFS_API SshOutputStreamBuffer : public std::streambuf 26 | { 27 | public: 28 | /** 29 | * @brief 30 | * Constructor 31 | * 32 | * @param[in] fs 33 | * File system that created this iterator 34 | * @param[in] path 35 | * Path to file or directory 36 | * @param[in] mode 37 | * Opening mode flags 38 | * @param[n] bufferSize 39 | * Size of the internal buffer 40 | * 41 | * @remarks 42 | * Do not set bufferSize to higher values, as libssh2 does not seem to 43 | * support it. Testing revealed any values heigher than 24k to fail 44 | * (files ended up not being written entirely). 45 | * 46 | * See https://c-ares.haxx.se/mail/libssh2-devel-archive-2010-02/0170.shtml 47 | */ 48 | SshOutputStreamBuffer(std::shared_ptr fs, const std::string & path, std::ios_base::openmode mode, size_t bufferSize = size_kb(24)); 49 | 50 | /** 51 | * @brief 52 | * Destructor 53 | */ 54 | virtual ~SshOutputStreamBuffer(); 55 | 56 | // Virtual streambuf functions 57 | virtual std::streambuf::int_type overflow(std::streambuf::int_type value) override; 58 | virtual int sync() override; 59 | virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which) override; 60 | virtual pos_type seekpos(pos_type pos, std::ios_base::openmode which) override; 61 | 62 | 63 | protected: 64 | std::shared_ptr m_fs; ///< File system that created this iterator 65 | const std::string m_path; ///< Path to file or directory 66 | void * m_file; ///< SFTP file handle 67 | std::vector m_buffer; ///< Write buffer 68 | }; 69 | 70 | 71 | } // namespace cppfs 72 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/system.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | /** 15 | * @brief 16 | * Access system information 17 | */ 18 | namespace system 19 | { 20 | 21 | 22 | /** 23 | * @brief 24 | * Get home directory of the current user 25 | * 26 | * @return 27 | * Home directory (native path) 28 | * 29 | * @remarks 30 | * It is assumed that the home directory doesn't change 31 | * for the process lifetime. 32 | */ 33 | CPPFS_API const std::string & homeDir(); 34 | 35 | /** 36 | * @brief 37 | * Get config directory for the named application 38 | * 39 | * @param[in] application 40 | * Application name 41 | * 42 | * @return 43 | * Config directory (native path) 44 | * 45 | * @remarks 46 | * It is assumed that the config directory doesn't change 47 | * for the process lifetime. 48 | */ 49 | CPPFS_API std::string configDir(const std::string & application); 50 | 51 | 52 | } // namespace system 53 | 54 | 55 | } // namespace cppfs 56 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/units.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | namespace cppfs 6 | { 7 | 8 | 9 | inline unsigned long long size_b(unsigned long long value) 10 | { 11 | return value; 12 | } 13 | 14 | inline unsigned long long size_kb(unsigned long long value) 15 | { 16 | return value * 1024; 17 | } 18 | 19 | inline unsigned long long size_mb(unsigned long long value) 20 | { 21 | return value * 1024 * 1024; 22 | } 23 | 24 | inline unsigned long long size_gb(unsigned long long value) 25 | { 26 | return value * 1024 * 1024 * 1024; 27 | } 28 | 29 | inline unsigned long long size_tb(unsigned long long value) 30 | { 31 | return value * 1024 * 1024 * 1024 * 1024; 32 | } 33 | 34 | 35 | /* 36 | // Unfortunately, user defined literals are not supported in VS 2013. 37 | // We should use this when we decide to drop support for VS 2013. 38 | 39 | inline unsigned long long operator""_B(unsigned long long value) 40 | { 41 | return value; 42 | } 43 | 44 | inline unsigned long long operator""_kB(unsigned long long value) 45 | { 46 | return value * 1024; 47 | } 48 | 49 | inline unsigned long long operator""_MB(unsigned long long value) 50 | { 51 | return value * 1024 * 1024; 52 | } 53 | 54 | inline unsigned long long operator""_GB(unsigned long long value) 55 | { 56 | return value * 1024 * 1024 * 1024; 57 | } 58 | 59 | inline unsigned long long operator""_TB(unsigned long long value) 60 | { 61 | return value * 1024 * 1024 * 1024 * 1024; 62 | } 63 | */ 64 | 65 | 66 | } // namespace cppfs 67 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/windows/LocalFileHandle.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | class LocalFileSystem; 15 | 16 | 17 | /** 18 | * @brief 19 | * File handle for the local file system 20 | */ 21 | class CPPFS_API LocalFileHandle : public AbstractFileHandleBackend 22 | { 23 | public: 24 | /** 25 | * @brief 26 | * Constructor 27 | * 28 | * @param[in] fs 29 | * File system that created this handle 30 | * @param[in] path 31 | * Path to file or directory 32 | */ 33 | LocalFileHandle(std::shared_ptr fs, const std::string & path); 34 | 35 | /** 36 | * @brief 37 | * Destructor 38 | */ 39 | virtual ~LocalFileHandle(); 40 | 41 | // Virtual AbstractFileHandleBackend functions 42 | virtual std::unique_ptr clone() const override; 43 | virtual AbstractFileSystem * fs() const override; 44 | virtual void updateFileInfo() override; 45 | virtual std::string path() const override; 46 | virtual bool exists() const override; 47 | virtual bool isFile() const override; 48 | virtual bool isDirectory() const override; 49 | virtual bool isSymbolicLink() const override; 50 | virtual std::vector listFiles() const override; 51 | virtual std::unique_ptr begin() const override; 52 | virtual unsigned int size() const override; 53 | virtual unsigned int accessTime() const override; 54 | virtual unsigned int modificationTime() const override; 55 | virtual unsigned int userId() const override; 56 | virtual void setUserId(unsigned int uid) override; 57 | virtual unsigned int groupId() const override; 58 | virtual void setGroupId(unsigned int gid) override; 59 | virtual unsigned long permissions() const override; 60 | virtual void setPermissions(unsigned long permissions) override; 61 | virtual bool createDirectory() override; 62 | virtual bool removeDirectory() override; 63 | virtual bool copy(AbstractFileHandleBackend & dest) override; 64 | virtual bool move(AbstractFileHandleBackend & dest) override; 65 | virtual bool createLink(AbstractFileHandleBackend & dest) override; 66 | virtual bool createSymbolicLink(AbstractFileHandleBackend & dest) override; 67 | virtual bool rename(const std::string & filename) override; 68 | virtual bool remove() override; 69 | virtual std::unique_ptr createInputStream(std::ios_base::openmode mode) const override; 70 | virtual std::unique_ptr createOutputStream(std::ios_base::openmode mode) override; 71 | 72 | 73 | protected: 74 | void readFileInfo() const; 75 | 76 | 77 | protected: 78 | std::shared_ptr m_fs; ///< File system that created this handle 79 | std::string m_path; ///< Path to file or directory 80 | mutable void * m_fileInfo; ///< Information about the current file (created on demand) 81 | }; 82 | 83 | 84 | } // namespace cppfs 85 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/windows/LocalFileIterator.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | class LocalFileSystem; 15 | 16 | 17 | /** 18 | * @brief 19 | * File iterator for the local file system 20 | */ 21 | class CPPFS_API LocalFileIterator : public AbstractFileIteratorBackend 22 | { 23 | public: 24 | /** 25 | * @brief 26 | * Constructor 27 | * 28 | * @param[in] fs 29 | * File system that created this iterator 30 | * @param[in] path 31 | * Path to file or directory 32 | */ 33 | LocalFileIterator(std::shared_ptr fs, const std::string & path); 34 | 35 | /** 36 | * @brief 37 | * Destructor 38 | */ 39 | virtual ~LocalFileIterator(); 40 | 41 | // Virtual AbstractFileIteratorBackend functions 42 | virtual std::unique_ptr clone() const override; 43 | virtual AbstractFileSystem * fs() const override; 44 | virtual bool valid() const override; 45 | virtual std::string path() const override; 46 | virtual int index() const override; 47 | virtual std::string name() const override; 48 | virtual void next() override; 49 | 50 | 51 | protected: 52 | void readNextEntry(); 53 | 54 | 55 | protected: 56 | std::shared_ptr m_fs; ///< File system that created this iterator 57 | std::string m_path; ///< Path to file or directory 58 | int m_index; ///< Index of the current entry 59 | void * m_findHandle; ///< Search handle 60 | void * m_findData; ///< Information about the current file 61 | }; 62 | 63 | 64 | } // namespace cppfs 65 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/windows/LocalFileSystem.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | /** 15 | * @brief 16 | * Representation of the local file system 17 | */ 18 | class CPPFS_API LocalFileSystem : public AbstractFileSystem, public std::enable_shared_from_this 19 | { 20 | public: 21 | /** 22 | * @brief 23 | * Constructor 24 | */ 25 | LocalFileSystem(); 26 | 27 | /** 28 | * @brief 29 | * Destructor 30 | */ 31 | virtual ~LocalFileSystem(); 32 | 33 | // Virtual AbstractFileSystem functions 34 | virtual FileHandle open(const std::string & path) override; 35 | virtual FileHandle open(std::string && path) override; 36 | virtual std::unique_ptr createFileWatcher(FileWatcher & fileWatcher) override; 37 | }; 38 | 39 | 40 | } // namespace cppfs 41 | -------------------------------------------------------------------------------- /source/cppfs/include/cppfs/windows/LocalFileWatcher.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #define WIN32_LEAN_AND_MEAN 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | 16 | namespace cppfs 17 | { 18 | 19 | 20 | class LocalFileSystem; 21 | 22 | 23 | /** 24 | * @brief 25 | * File watcher for the local file system 26 | */ 27 | class CPPFS_API LocalFileWatcher : public AbstractFileWatcherBackend 28 | { 29 | public: 30 | /** 31 | * @brief 32 | * Constructor 33 | * 34 | * @param[in] fileWatcher 35 | * File watcher that owns the backend (must NOT be null!) 36 | * @param[in] fs 37 | * File system that created this watcher 38 | */ 39 | LocalFileWatcher(FileWatcher * fileWatcher, std::shared_ptr fs); 40 | 41 | /** 42 | * @brief 43 | * Destructor 44 | */ 45 | virtual ~LocalFileWatcher(); 46 | 47 | // Virtual AbstractFileWatcherBackend functions 48 | virtual AbstractFileSystem * fs() const override; 49 | virtual void add(FileHandle & dir, unsigned int events, RecursiveMode recursive) override; 50 | virtual void watch(int timeout) override; 51 | 52 | 53 | protected: 54 | /** 55 | * @brief 56 | * Watcher entry 57 | */ 58 | struct Watcher { 59 | FileHandle dir; ///< Directory that is watched 60 | unsigned int events; ///< Watched events 61 | RecursiveMode recursive; ///< Watch recursively? 62 | std::shared_ptr dirHandle; ///< Handle for the directory 63 | std::shared_ptr event; ///< Event that is triggered for this watcher 64 | ::OVERLAPPED overlapped; ///< Overlapped data (for asynchronous operation) 65 | char buffer[16384]; ///< Buffer for overlapped data (1024 * sizeof(FILE_NOTIFY_INFORMATION)) 66 | }; 67 | 68 | 69 | protected: 70 | std::shared_ptr m_fs; ///< File system that created this watcher 71 | std::vector m_watchers; ///< List of watchers 72 | ::HANDLE m_waitStopEvent; ///< Event to stop watch function 73 | ::CRITICAL_SECTION m_mutexWatchers; ///< Mutex/critical section for accessing m_watchers 74 | }; 75 | 76 | 77 | } // namespace cppfs 78 | -------------------------------------------------------------------------------- /source/cppfs/source/AbstractFileHandleBackend.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | 5 | namespace cppfs 6 | { 7 | 8 | 9 | AbstractFileHandleBackend::AbstractFileHandleBackend() 10 | { 11 | } 12 | 13 | AbstractFileHandleBackend::~AbstractFileHandleBackend() 14 | { 15 | } 16 | 17 | 18 | } // namespace cppfs 19 | -------------------------------------------------------------------------------- /source/cppfs/source/AbstractFileIteratorBackend.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | 5 | namespace cppfs 6 | { 7 | 8 | 9 | AbstractFileIteratorBackend::AbstractFileIteratorBackend() 10 | { 11 | } 12 | 13 | AbstractFileIteratorBackend::~AbstractFileIteratorBackend() 14 | { 15 | } 16 | 17 | 18 | } // namespace cppfs 19 | -------------------------------------------------------------------------------- /source/cppfs/source/AbstractFileSystem.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | 7 | namespace cppfs 8 | { 9 | 10 | 11 | AbstractFileSystem::AbstractFileSystem() 12 | { 13 | } 14 | 15 | AbstractFileSystem::~AbstractFileSystem() 16 | { 17 | } 18 | 19 | 20 | } // namespace cppfs 21 | -------------------------------------------------------------------------------- /source/cppfs/source/AbstractFileWatcherBackend.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | 7 | namespace cppfs 8 | { 9 | 10 | 11 | AbstractFileWatcherBackend::AbstractFileWatcherBackend(FileWatcher * fileWatcher) 12 | : m_fileWatcher(fileWatcher) 13 | { 14 | } 15 | 16 | AbstractFileWatcherBackend::~AbstractFileWatcherBackend() 17 | { 18 | } 19 | 20 | void AbstractFileWatcherBackend::onFileEvent(FileHandle & fh, FileEvent event) 21 | { 22 | m_fileWatcher->onFileEvent(fh, event); 23 | } 24 | 25 | 26 | } // namespace cppfs 27 | -------------------------------------------------------------------------------- /source/cppfs/source/Change.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | 5 | namespace cppfs 6 | { 7 | 8 | 9 | Change::Change() 10 | : m_operation(Change::None) 11 | , m_path("") 12 | { 13 | } 14 | 15 | Change::Change(Operation operation, const std::string & path) 16 | : m_operation(operation) 17 | , m_path(path) 18 | { 19 | } 20 | 21 | Change::Change(Operation operation, std::string && path) 22 | : m_operation(operation) 23 | , m_path(std::move(path)) 24 | { 25 | } 26 | 27 | Change::Change(const Change & change) 28 | : m_operation(change.m_operation) 29 | , m_path(change.m_path) 30 | { 31 | } 32 | 33 | Change::Change(Change && change) 34 | : m_operation(std::move(change.m_operation)) 35 | , m_path(std::move(change.m_path)) 36 | { 37 | } 38 | 39 | Change::~Change() 40 | { 41 | } 42 | 43 | Change & Change::operator=(const Change & change) 44 | { 45 | m_operation = change.m_operation; 46 | m_path = change.m_path; 47 | 48 | return *this; 49 | } 50 | 51 | Change & Change::operator=(Change && change) 52 | { 53 | m_operation = std::move(change.m_operation); 54 | m_path = std::move(change.m_path); 55 | 56 | return *this; 57 | } 58 | 59 | std::string Change::toString() const 60 | { 61 | switch (m_operation) 62 | { 63 | case Change::CopyFile: return "CP " + m_path; 64 | case Change::CopyDir: return "CPDIR " + m_path; 65 | case Change::RemoveFile: return "RM " + m_path; 66 | case Change::RemoveDir: return "RMDIR " + m_path; 67 | default: return "NOOP"; 68 | } 69 | } 70 | 71 | Change::Operation Change::operation() const 72 | { 73 | return m_operation; 74 | } 75 | 76 | const std::string & Change::path() const 77 | { 78 | return m_path; 79 | } 80 | 81 | 82 | } // namespace cppfs 83 | -------------------------------------------------------------------------------- /source/cppfs/source/Diff.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | 7 | namespace cppfs 8 | { 9 | 10 | 11 | Diff::Diff() 12 | { 13 | } 14 | 15 | Diff::~Diff() 16 | { 17 | } 18 | 19 | void Diff::clear() 20 | { 21 | m_changes.clear(); 22 | } 23 | 24 | const std::vector & Diff::changes() const 25 | { 26 | return m_changes; 27 | } 28 | 29 | void Diff::add(const Change & change) 30 | { 31 | m_changes.push_back(change); 32 | } 33 | 34 | void Diff::add(Change && change) 35 | { 36 | m_changes.push_back(change); 37 | } 38 | 39 | void Diff::add(Change::Operation operation, const std::string & path) 40 | { 41 | m_changes.emplace_back(operation, path); 42 | } 43 | 44 | void Diff::add(Change::Operation operation, std::string && path) 45 | { 46 | m_changes.emplace_back(operation, path); 47 | } 48 | 49 | void Diff::print(std::ostream & stream) 50 | { 51 | for (size_t i = 0; i < m_changes.size(); i++) 52 | { 53 | stream << m_changes[i].toString() << std::endl; 54 | } 55 | } 56 | 57 | void Diff::print() 58 | { 59 | print(std::cout); 60 | } 61 | 62 | 63 | } // namespace cppfs 64 | -------------------------------------------------------------------------------- /source/cppfs/source/FileEventHandler.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | 7 | namespace cppfs 8 | { 9 | 10 | 11 | FileEventHandler::FileEventHandler() 12 | { 13 | } 14 | 15 | FileEventHandler::~FileEventHandler() 16 | { 17 | } 18 | 19 | void FileEventHandler::onFileEvent(FileHandle & fh, FileEvent event) 20 | { 21 | switch (event) { 22 | case FileCreated: 23 | onFileCreated(fh); 24 | break; 25 | 26 | case FileRemoved: 27 | onFileRemoved(fh); 28 | break; 29 | 30 | case FileModified: 31 | onFileModified(fh); 32 | break; 33 | 34 | case FileAttrChanged: 35 | onFileAttrChanged(fh); 36 | break; 37 | 38 | default: 39 | break; 40 | } 41 | } 42 | 43 | void FileEventHandler::onFileCreated(FileHandle &) 44 | { 45 | } 46 | 47 | void FileEventHandler::onFileRemoved(FileHandle &) 48 | { 49 | } 50 | 51 | void FileEventHandler::onFileModified(FileHandle &) 52 | { 53 | } 54 | 55 | void FileEventHandler::onFileAttrChanged(FileHandle &) 56 | { 57 | } 58 | 59 | 60 | } // namespace cppfs 61 | -------------------------------------------------------------------------------- /source/cppfs/source/FileIterator.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | 7 | namespace cppfs 8 | { 9 | 10 | 11 | FileIterator::FileIterator() 12 | { 13 | } 14 | 15 | FileIterator::FileIterator(std::unique_ptr && backend) 16 | : m_backend(std::move(backend)) 17 | { 18 | } 19 | 20 | FileIterator::FileIterator(const FileIterator & fileIterator) 21 | : m_backend(fileIterator.m_backend ? fileIterator.m_backend->clone() : nullptr) 22 | { 23 | } 24 | 25 | FileIterator::FileIterator(FileIterator && fileIterator) 26 | : m_backend(std::move(fileIterator.m_backend)) 27 | { 28 | } 29 | 30 | FileIterator::~FileIterator() 31 | { 32 | } 33 | 34 | FileIterator & FileIterator::operator=(const FileIterator & fileIterator) 35 | { 36 | if (fileIterator.m_backend) 37 | { 38 | m_backend = fileIterator.m_backend->clone(); 39 | } 40 | else 41 | { 42 | m_backend.reset(nullptr); 43 | } 44 | 45 | return *this; 46 | } 47 | 48 | std::string FileIterator::operator*() const 49 | { 50 | return m_backend ? m_backend->name() : ""; 51 | } 52 | 53 | void FileIterator::operator++() 54 | { 55 | if (m_backend) 56 | { 57 | m_backend->next(); 58 | } 59 | } 60 | 61 | bool FileIterator::operator==(const FileIterator & it) const 62 | { 63 | bool valid1 = false; 64 | bool valid2 = false; 65 | AbstractFileSystem * fs1 = nullptr; 66 | AbstractFileSystem * fs2 = nullptr; 67 | std::string path1; 68 | std::string path2; 69 | int index1 = -1; 70 | int index2 = -1; 71 | 72 | // Check if both iterators operate on the same file system 73 | fs1 = ( m_backend ? m_backend->fs() : nullptr); 74 | fs2 = (it.m_backend ? it.m_backend->fs() : nullptr); 75 | 76 | // Get status of first iterator 77 | if (m_backend && m_backend->valid()) 78 | { 79 | valid1 = true; 80 | index1 = m_backend->index(); 81 | path1 = m_backend->path(); 82 | } 83 | 84 | // Get status of second iterator 85 | if (it.m_backend && it.m_backend->valid()) 86 | { 87 | valid2 = true; 88 | index2 = it.m_backend->index(); 89 | path2 = it.m_backend->path(); 90 | } 91 | 92 | // If both iterators are valid, check if they are equal 93 | if (valid1 && valid2) 94 | { 95 | return fs1 == fs2 && path1 == path2 && index1 == index2; 96 | } 97 | 98 | // Otherwise, consider them equal if both are invalid 99 | else 100 | { 101 | return valid1 == valid2; 102 | } 103 | } 104 | 105 | bool FileIterator::operator!=(const FileIterator & it) const 106 | { 107 | return !((*this) == it); 108 | } 109 | 110 | AbstractFileSystem * FileIterator::fs() const 111 | { 112 | return m_backend ? m_backend->fs() : nullptr; 113 | } 114 | 115 | 116 | } // namespace cppfs 117 | -------------------------------------------------------------------------------- /source/cppfs/source/FileVisitor.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | 7 | namespace cppfs 8 | { 9 | 10 | 11 | FileVisitor::FileVisitor() 12 | { 13 | } 14 | 15 | FileVisitor::~FileVisitor() 16 | { 17 | } 18 | 19 | bool FileVisitor::onFileEntry(FileHandle & fh) 20 | { 21 | if (fh.isDirectory()) 22 | { 23 | return onDirectory(fh); 24 | } 25 | 26 | else 27 | { 28 | return onFile(fh); 29 | } 30 | } 31 | 32 | bool FileVisitor::onFile(FileHandle &) 33 | { 34 | return true; 35 | } 36 | 37 | bool FileVisitor::onDirectory(FileHandle &) 38 | { 39 | return true; 40 | } 41 | 42 | 43 | } // namespace cppfs 44 | -------------------------------------------------------------------------------- /source/cppfs/source/FileWatcher.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | namespace cppfs 13 | { 14 | 15 | 16 | FileWatcher::FileWatcher() 17 | : m_backend(fs::localFS()->createFileWatcher(*this)) 18 | { 19 | } 20 | 21 | FileWatcher::FileWatcher(AbstractFileSystem * fs) 22 | : m_backend(fs ? fs->createFileWatcher(*this) : nullptr) 23 | { 24 | } 25 | 26 | FileWatcher::FileWatcher(FileWatcher && fileWatcher) 27 | : m_backend(std::move(fileWatcher.m_backend)) 28 | , m_eventHandlers(std::move(fileWatcher.m_eventHandlers)) 29 | , m_ownEventHandlers(std::move(fileWatcher.m_ownEventHandlers)) 30 | { 31 | // Fix pointer to file watcher 32 | if (m_backend) { 33 | m_backend->m_fileWatcher = this; 34 | } 35 | } 36 | 37 | FileWatcher::~FileWatcher() 38 | { 39 | } 40 | 41 | FileWatcher & FileWatcher::operator=(FileWatcher && fileWatcher) 42 | { 43 | // Move backend 44 | m_backend = std::move(fileWatcher.m_backend); 45 | m_eventHandlers = std::move(fileWatcher.m_eventHandlers); 46 | m_ownEventHandlers = std::move(fileWatcher.m_ownEventHandlers); 47 | 48 | // Fix pointer to file watcher 49 | if (m_backend) { 50 | m_backend->m_fileWatcher = this; 51 | } 52 | 53 | // Done 54 | return *this; 55 | } 56 | 57 | AbstractFileSystem * FileWatcher::fs() const 58 | { 59 | return m_backend ? m_backend->fs() : nullptr; 60 | } 61 | 62 | void FileWatcher::add(FileHandle & dir, unsigned int events, RecursiveMode recursive) 63 | { 64 | // Check backend 65 | if (!m_backend) { 66 | return; 67 | } 68 | 69 | // Check that file handle is a directory and belongs to the same file system as the watcher 70 | if (!dir.isDirectory() || dir.fs() != fs()) { 71 | return; 72 | } 73 | 74 | // Add directory to watcher 75 | m_backend->add(dir, events, recursive); 76 | } 77 | 78 | void FileWatcher::addHandler(FileEventHandler * eventHandler) 79 | { 80 | // Check that event handler is valid and not already registered 81 | if (!eventHandler || std::find(m_eventHandlers.begin(), m_eventHandlers.end(), eventHandler) != m_eventHandlers.end()) { 82 | return; 83 | } 84 | 85 | // Add event handler to list 86 | m_eventHandlers.push_back(eventHandler); 87 | } 88 | 89 | void FileWatcher::addHandler(EventFunc funcFileEvent) 90 | { 91 | // Create event handler 92 | auto ptr = std::unique_ptr(new FunctionalFileEventHandler(std::move(funcFileEvent))); 93 | 94 | // Register event handler 95 | addHandler(ptr.get()); 96 | 97 | // Take ownership 98 | m_ownEventHandlers.push_back(std::move(ptr)); 99 | } 100 | 101 | void FileWatcher::removeHandler(FileEventHandler * eventHandler) 102 | { 103 | // Check if event handler is registered 104 | auto it = std::find(m_eventHandlers.begin(), m_eventHandlers.end(), eventHandler); 105 | if (it != m_eventHandlers.end()) { 106 | // Remove event handler 107 | m_eventHandlers.erase(it); 108 | } 109 | } 110 | 111 | void FileWatcher::watch(int timeout) 112 | { 113 | // Check backend 114 | if (!m_backend) { 115 | return; 116 | } 117 | 118 | // Watch files 119 | m_backend->watch(timeout); 120 | } 121 | 122 | void FileWatcher::onFileEvent(FileHandle & fh, FileEvent event) 123 | { 124 | // Call file event handlers 125 | for (auto * eventHandler : m_eventHandlers) { 126 | eventHandler->onFileEvent(fh, event); 127 | } 128 | } 129 | 130 | 131 | } // name cppfs 132 | -------------------------------------------------------------------------------- /source/cppfs/source/FunctionalFileEventHandler.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | 5 | namespace cppfs 6 | { 7 | 8 | 9 | FunctionalFileEventHandler::FunctionalFileEventHandler() 10 | { 11 | } 12 | 13 | FunctionalFileEventHandler::FunctionalFileEventHandler(EventFunc funcFileEvent) 14 | : m_funcFileEvent(std::move(funcFileEvent)) 15 | { 16 | } 17 | 18 | FunctionalFileEventHandler::~FunctionalFileEventHandler() 19 | { 20 | } 21 | 22 | void FunctionalFileEventHandler::onFileEvent(FileHandle & fh, FileEvent event) 23 | { 24 | if (m_funcFileEvent) 25 | { 26 | m_funcFileEvent(fh, event); 27 | } 28 | } 29 | 30 | 31 | } // namespace cppfs 32 | -------------------------------------------------------------------------------- /source/cppfs/source/FunctionalFileVisitor.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | 7 | namespace cppfs 8 | { 9 | 10 | 11 | FunctionalFileVisitor::FunctionalFileVisitor() 12 | { 13 | } 14 | 15 | FunctionalFileVisitor::FunctionalFileVisitor(VisitFunc funcFileEntry) 16 | : m_funcFileEntry(std::move(funcFileEntry)) 17 | { 18 | } 19 | 20 | FunctionalFileVisitor::FunctionalFileVisitor(VisitFunc funcFile, VisitFunc funcDirectory) 21 | : m_funcFile(std::move(funcFile)) 22 | , m_funcDirectory(std::move(funcDirectory)) 23 | { 24 | } 25 | 26 | FunctionalFileVisitor::~FunctionalFileVisitor() 27 | { 28 | } 29 | 30 | bool FunctionalFileVisitor::onFileEntry(FileHandle & fh) 31 | { 32 | if (m_funcFileEntry) 33 | { 34 | return m_funcFileEntry(fh); 35 | } 36 | 37 | else if (fh.isDirectory()) 38 | { 39 | return onDirectory(fh); 40 | } 41 | 42 | else if (fh.isFile()) 43 | { 44 | return onFile(fh); 45 | } 46 | 47 | return false; 48 | } 49 | 50 | bool FunctionalFileVisitor::onFile(FileHandle & fh) 51 | { 52 | if (m_funcFile) 53 | { 54 | return m_funcFile(fh); 55 | } 56 | 57 | return false; 58 | } 59 | 60 | bool FunctionalFileVisitor::onDirectory(FileHandle & fh) 61 | { 62 | if (m_funcDirectory) 63 | { 64 | return m_funcDirectory(fh); 65 | } 66 | 67 | return false; 68 | } 69 | 70 | 71 | } // namespace cppfs 72 | -------------------------------------------------------------------------------- /source/cppfs/source/InputStream.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | 5 | namespace cppfs 6 | { 7 | 8 | 9 | InputStream::InputStream(std::streambuf * sb) 10 | : std::istream(sb) 11 | , m_sb(sb) 12 | { 13 | } 14 | 15 | InputStream::~InputStream() 16 | { 17 | delete m_sb; 18 | } 19 | 20 | 21 | } // namespace cppfs 22 | -------------------------------------------------------------------------------- /source/cppfs/source/LoginCredentials.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | 12 | namespace 13 | { 14 | 15 | 16 | const std::string emptyValue = ""; 17 | 18 | 19 | } // namespace 20 | 21 | 22 | namespace cppfs 23 | { 24 | 25 | 26 | LoginCredentials::LoginCredentials() 27 | { 28 | } 29 | 30 | LoginCredentials::LoginCredentials(const LoginCredentials & loginCredentials) 31 | : m_values(loginCredentials.m_values) 32 | { 33 | } 34 | 35 | LoginCredentials::LoginCredentials(const LoginCredentials && loginCredentials) 36 | : m_values(std::move(loginCredentials.m_values)) 37 | { 38 | } 39 | 40 | LoginCredentials::~LoginCredentials() 41 | { 42 | } 43 | 44 | LoginCredentials & LoginCredentials::operator=(const LoginCredentials & loginCredentials) 45 | { 46 | m_values = loginCredentials.m_values; 47 | 48 | return *this; 49 | } 50 | 51 | LoginCredentials & LoginCredentials::operator=(LoginCredentials && loginCredentials) 52 | { 53 | m_values = std::move(loginCredentials.m_values); 54 | 55 | return *this; 56 | } 57 | 58 | bool LoginCredentials::load(const std::string & path) 59 | { 60 | // Open file 61 | FileHandle file = fs::open(path); 62 | if (!file.isFile()) return false; 63 | 64 | // Open input stream 65 | auto in = file.createInputStream(); 66 | if (!in) return false; 67 | 68 | // Get all keys and values 69 | std::string line; 70 | while (std::getline(*in, line)) 71 | { 72 | auto pos = line.find(": "); 73 | 74 | if (pos != std::string::npos) 75 | { 76 | std::string key = line.substr(0, pos); 77 | std::string value = line.substr(pos + 2); 78 | 79 | setValue(key, value); 80 | } 81 | } 82 | 83 | // Done 84 | return true; 85 | } 86 | 87 | bool LoginCredentials::save(const std::string & path) const 88 | { 89 | // Open file 90 | FileHandle file = fs::open(path); 91 | 92 | // Open output stream 93 | auto out = file.createOutputStream(); 94 | if (!out) return false; 95 | 96 | // Get all keys and values 97 | for (auto it : m_values) 98 | { 99 | const std::string & key = it.first; 100 | const std::string & value = it.second; 101 | 102 | if (!key.empty() && !value.empty()) 103 | { 104 | (*out) << key << ": " << value << std::endl; 105 | } 106 | } 107 | 108 | // Done 109 | return true; 110 | } 111 | 112 | bool LoginCredentials::isSet(const std::string & key) const 113 | { 114 | return (m_values.find(key) != m_values.end()); 115 | } 116 | 117 | const std::string & LoginCredentials::value(const std::string & key) const 118 | { 119 | const auto it = m_values.find(key); 120 | 121 | if (it != m_values.end()) 122 | { 123 | return it->second; 124 | } 125 | 126 | return emptyValue; 127 | } 128 | 129 | void LoginCredentials::setValue(const std::string & key, const std::string & value) 130 | { 131 | m_values[key] = value; 132 | } 133 | 134 | void LoginCredentials::setValue(const std::string & key, std::string && value) 135 | { 136 | m_values[key] = std::move(value); 137 | } 138 | 139 | 140 | } // namespace cppfs 141 | -------------------------------------------------------------------------------- /source/cppfs/source/OutputStream.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | 5 | namespace cppfs 6 | { 7 | 8 | 9 | OutputStream::OutputStream(std::streambuf * sb) 10 | : std::ostream(sb) 11 | , m_sb(sb) 12 | { 13 | } 14 | 15 | OutputStream::~OutputStream() 16 | { 17 | m_sb->pubsync(); 18 | delete m_sb; 19 | } 20 | 21 | 22 | } // namespace cppfs 23 | -------------------------------------------------------------------------------- /source/cppfs/source/fs.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #if defined(__APPLE__) 11 | #define COMMON_DIGEST_FOR_OPENSSL 12 | #include 13 | #define SHA1 CC_SHA1 14 | #include 15 | #elif defined(CPPFS_USE_OpenSSL) 16 | #include 17 | #include 18 | #endif 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #ifdef SYSTEM_WINDOWS 28 | #include 29 | #else 30 | #include 31 | #endif 32 | 33 | 34 | namespace cppfs 35 | { 36 | namespace fs 37 | { 38 | 39 | 40 | std::shared_ptr localFS() 41 | { 42 | static std::shared_ptr fs(new LocalFileSystem); 43 | 44 | return fs; 45 | } 46 | 47 | FileHandle open(const std::string & path, const LoginCredentials * credentials) 48 | { 49 | // Parse url 50 | Url url(path); 51 | 52 | // Determine filesystem backend from path/url 53 | 54 | // SSH 55 | if (url.protocol() == "ssh://") 56 | { 57 | #if defined(CPPFS_USE_OpenSSL) 58 | // Get connection parameters 59 | std::string host = url.host(); 60 | std::string user = url.username(); 61 | std::string pass = url.password(); 62 | std::string localPath = url.path(); 63 | int port = 22; 64 | std::string publicKey = system::homeDir() + "/.ssh/id_rsa.pub"; 65 | std::string privateKey = system::homeDir() + "/.ssh/id_rsa"; 66 | 67 | // Apply login credentials 68 | if (credentials) 69 | { 70 | if (credentials->isSet("port")) port = std::stoi(credentials->value("port")); 71 | if (credentials->isSet("username")) user = credentials->value("username"); 72 | if (credentials->isSet("password")) pass = credentials->value("password"); 73 | if (credentials->isSet("publicKey")) publicKey = credentials->value("publicKey"); 74 | if (credentials->isSet("privateKey")) privateKey = credentials->value("privateKey"); 75 | } 76 | 77 | // Create SSH connection 78 | std::shared_ptr fs( 79 | new SshFileSystem(host, port, user, pass, publicKey, privateKey) 80 | ); 81 | 82 | // Open path 83 | return fs->open(localPath); 84 | #else 85 | return FileHandle(); 86 | #endif 87 | } 88 | 89 | // Local file system 90 | else 91 | { 92 | // Get local path 93 | std::string localPath = url.path(); 94 | 95 | // Open local file system 96 | auto fs = localFS(); 97 | 98 | // Open path 99 | return fs->open(localPath); 100 | } 101 | } 102 | 103 | std::string sha1(const std::string & str) 104 | { 105 | #ifdef CPPFS_USE_OpenSSL 106 | // Initialize hash 107 | unsigned char hash[20]; 108 | SHA_CTX context; 109 | SHA1_Init(&context); 110 | 111 | // Update hash 112 | SHA1_Update(&context, str.c_str(), str.size()); 113 | 114 | // Compute hash 115 | SHA1_Final(hash, &context); 116 | return hashToString(hash); 117 | #else 118 | return ""; 119 | #endif 120 | } 121 | 122 | std::string base64(const std::string & str) 123 | { 124 | // Encode base64 125 | std::string base64; 126 | bn::encode_b64(str.begin(), str.end(), back_inserter(base64)); 127 | 128 | // Return encoded string 129 | return base64; 130 | } 131 | 132 | std::string fromBase64(const std::string & base64) 133 | { 134 | // Decode base64 135 | std::string str; 136 | bn::decode_b64(base64.begin(), base64.end(), back_inserter(str)); 137 | 138 | // Return decoded string 139 | return str; 140 | } 141 | 142 | std::string hashToString(const unsigned char * hash) 143 | { 144 | std::stringstream stream; 145 | stream << std::hex << std::setfill('0') << std::setw(2); 146 | 147 | for (int i=0; i<20; i++) 148 | { 149 | stream << static_cast(hash[i]); 150 | } 151 | 152 | return stream.str(); 153 | } 154 | 155 | 156 | } // namespace fs 157 | } // namespace cppfs 158 | -------------------------------------------------------------------------------- /source/cppfs/source/linux/LocalFileWatcher.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | namespace cppfs 19 | { 20 | 21 | 22 | LocalFileWatcher::LocalFileWatcher(FileWatcher * fileWatcher, std::shared_ptr fs) 23 | : AbstractFileWatcherBackend(fileWatcher) 24 | , m_fs(std::move(fs)) 25 | , m_inotify(-1) 26 | { 27 | // Create inotify instance 28 | m_inotify = inotify_init(); 29 | } 30 | 31 | LocalFileWatcher::~LocalFileWatcher() 32 | { 33 | // Close watch handles 34 | for (auto it : m_watchers) { 35 | inotify_rm_watch(m_inotify, it.first); 36 | } 37 | 38 | // Close inotify instance 39 | close(m_inotify); 40 | } 41 | 42 | AbstractFileSystem * LocalFileWatcher::fs() const 43 | { 44 | // Return file system 45 | return static_cast(m_fs.get()); 46 | } 47 | 48 | void LocalFileWatcher::add(FileHandle & dir, unsigned int events, RecursiveMode recursive) 49 | { 50 | // Get watch mode 51 | uint32_t flags = 0; 52 | if (events & FileCreated) flags |= IN_CREATE; 53 | if (events & FileRemoved) flags |= IN_DELETE; 54 | if (events & FileModified) flags |= IN_MODIFY; 55 | if (events & FileAttrChanged) flags |= IN_ATTRIB; 56 | 57 | 58 | // Create watcher 59 | int handle = inotify_add_watch(m_inotify, dir.path().c_str(), flags); 60 | if (handle < 0) { 61 | return; 62 | } 63 | 64 | // Watch directories recursively 65 | if (recursive == Recursive) { 66 | // List directory entries 67 | for (auto it = dir.begin(); it != dir.end(); ++it) 68 | { 69 | // Check if entry is a directory 70 | FileHandle fh2 = dir.open(*it); 71 | if (fh2.isDirectory()) { 72 | // Watch directory 73 | add(fh2, events, recursive); 74 | } 75 | } 76 | } 77 | 78 | // Associate watcher handle with file handle 79 | m_watchers[handle].dir = dir; 80 | m_watchers[handle].events = events; 81 | m_watchers[handle].recursive = recursive; 82 | } 83 | 84 | void LocalFileWatcher::watch(int timeout) 85 | { 86 | // Create buffer for receiving events 87 | size_t bufSize = 64 * (sizeof(inotify_event) + NAME_MAX); 88 | std::vector buffer; 89 | buffer.resize(bufSize); 90 | 91 | // Set timeout 92 | if (timeout >= 0) { 93 | // Create file descriptor set 94 | fd_set set; 95 | FD_ZERO(&set); 96 | FD_SET(m_inotify, &set); 97 | 98 | // Convert timeout into timeval struct 99 | struct timeval tval; 100 | tval.tv_sec = timeout / 1000; 101 | tval.tv_usec = (timeout - tval.tv_sec * 1000) * 1000; 102 | 103 | // Set timeout on file descriptor 104 | int rv = select(m_inotify + 1, &set, NULL, NULL, &tval); 105 | if (rv <= 0) { 106 | return; 107 | } 108 | } 109 | 110 | // Read events 111 | int size = read(m_inotify, buffer.data(), bufSize); 112 | if (size < 0) { 113 | return; 114 | } 115 | 116 | // Process all events 117 | int i = 0; 118 | while (i < size) { 119 | // Get event 120 | auto * event = reinterpret_cast(&buffer.data()[i]); 121 | if (event->len) { 122 | // Get event 123 | FileEvent eventType = (FileEvent)0; 124 | if (event->mask & IN_CREATE) eventType = FileCreated; 125 | else if (event->mask & IN_DELETE) eventType = FileRemoved; 126 | else if (event->mask & IN_MODIFY) eventType = FileModified; 127 | else if (event->mask & IN_ATTRIB) eventType = FileAttrChanged; 128 | 129 | // Get watcher 130 | auto & watcher = m_watchers[event->wd]; 131 | 132 | // Get file handle 133 | FileHandle fh = (event->len > 0 ? watcher.dir.open(std::string(event->name)) : watcher.dir); 134 | 135 | // Watch new directories 136 | if (fh.isDirectory() && eventType == FileCreated && watcher.recursive == Recursive) { 137 | add(fh, watcher.events, watcher.recursive); 138 | } 139 | 140 | // Invoke callback function 141 | onFileEvent(fh, eventType); 142 | } 143 | 144 | // Next event 145 | i += sizeof(inotify_event) + event->len; 146 | } 147 | } 148 | 149 | 150 | } // namespace cppfs 151 | -------------------------------------------------------------------------------- /source/cppfs/source/posix/LocalFileIterator.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | LocalFileIterator::LocalFileIterator(std::shared_ptr fs, const std::string & path) 15 | : LocalFileIterator(std::move(fs), std::string(path)) 16 | { 17 | } 18 | 19 | LocalFileIterator::LocalFileIterator(std::shared_ptr fs, std::string && path) 20 | : m_fs(std::move(fs)) 21 | , m_path(path) 22 | , m_dir(nullptr) 23 | , m_entry(nullptr) 24 | , m_index(-1) 25 | { 26 | // Open directory 27 | m_dir = opendir(m_path.c_str()); 28 | 29 | // Read first directory entry 30 | readNextEntry(); 31 | } 32 | 33 | LocalFileIterator::~LocalFileIterator() 34 | { 35 | if (m_dir) 36 | { 37 | closedir(m_dir); 38 | } 39 | } 40 | 41 | std::unique_ptr LocalFileIterator::clone() const 42 | { 43 | auto * twin = new LocalFileIterator(m_fs, m_path); 44 | 45 | while (twin->m_index < m_index) 46 | { 47 | twin->readNextEntry(); 48 | } 49 | 50 | return std::unique_ptr(twin); 51 | } 52 | 53 | AbstractFileSystem * LocalFileIterator::fs() const 54 | { 55 | return static_cast(m_fs.get()); 56 | } 57 | 58 | bool LocalFileIterator::valid() const 59 | { 60 | return (m_dir != nullptr && m_entry != nullptr); 61 | } 62 | 63 | std::string LocalFileIterator::path() const 64 | { 65 | return m_path; 66 | } 67 | 68 | int LocalFileIterator::index() const 69 | { 70 | return m_index; 71 | } 72 | 73 | std::string LocalFileIterator::name() const 74 | { 75 | // Check directory and entry handle 76 | if (!m_dir || !m_entry) 77 | { 78 | return ""; 79 | } 80 | 81 | // Return filename of current item 82 | // m_entry->d_name is an array, not a pointer, so it cannot be nullptr. If m_entry is valid, d_name is also valid. 83 | return std::string(m_entry->d_name); 84 | } 85 | 86 | void LocalFileIterator::next() 87 | { 88 | readNextEntry(); 89 | } 90 | 91 | void LocalFileIterator::readNextEntry() 92 | { 93 | // Check directory handle 94 | if (!m_dir) return; 95 | 96 | // Read next entry 97 | m_entry = readdir(m_dir); 98 | m_index++; 99 | if (!m_entry) return; 100 | 101 | // Omit '.' and '..' 102 | std::string name(m_entry->d_name); 103 | while (m_entry && (name == ".." || name == ".")) 104 | { 105 | m_entry = readdir(m_dir); 106 | 107 | name = m_entry ? std::string(m_entry->d_name) : std::string(); 108 | } 109 | } 110 | 111 | 112 | } // namespace cppfs 113 | -------------------------------------------------------------------------------- /source/cppfs/source/posix/LocalFileSystem.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef SYSTEM_LINUX 10 | #include 11 | #endif 12 | 13 | 14 | namespace cppfs 15 | { 16 | 17 | 18 | LocalFileSystem::LocalFileSystem() 19 | { 20 | } 21 | 22 | LocalFileSystem::~LocalFileSystem() 23 | { 24 | } 25 | 26 | FileHandle LocalFileSystem::open(const std::string & path) 27 | { 28 | return open(std::string(path)); 29 | } 30 | 31 | FileHandle LocalFileSystem::open(std::string && path) 32 | { 33 | return FileHandle( 34 | std::unique_ptr( 35 | new LocalFileHandle(shared_from_this(), std::move(path)) 36 | ) 37 | ); 38 | } 39 | 40 | std::unique_ptr LocalFileSystem::createFileWatcher(FileWatcher & fileWatcher) 41 | { 42 | #ifdef SYSTEM_LINUX 43 | return std::unique_ptr( 44 | new LocalFileWatcher(&fileWatcher, shared_from_this()) 45 | ); 46 | #else 47 | return nullptr; 48 | #endif 49 | } 50 | 51 | 52 | } // namespace cppfs 53 | -------------------------------------------------------------------------------- /source/cppfs/source/ssh/SshFileIterator.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | 8 | 9 | namespace cppfs 10 | { 11 | 12 | 13 | SshFileIterator::SshFileIterator(std::shared_ptr fs, const std::string & path) 14 | : m_fs(fs) 15 | , m_path(path) 16 | , m_dir(nullptr) 17 | , m_index(-1) 18 | { 19 | // Check handle 20 | if (!m_fs->m_session) return; 21 | 22 | // Initialize SFTP sub-protocol 23 | m_fs->initSftp(); 24 | 25 | // Check handle 26 | if (!m_fs->m_sftpSession) return; 27 | 28 | // Open directory 29 | m_dir = libssh2_sftp_opendir((LIBSSH2_SFTP *)m_fs->m_sftpSession, m_path.c_str()); 30 | 31 | // Read first directory entry 32 | readNextEntry(); 33 | } 34 | 35 | SshFileIterator::~SshFileIterator() 36 | { 37 | if (m_dir) 38 | { 39 | libssh2_sftp_closedir(m_dir); 40 | } 41 | } 42 | 43 | std::unique_ptr SshFileIterator::clone() const 44 | { 45 | auto * twin = new SshFileIterator(m_fs, m_path); 46 | 47 | while (twin->m_index < m_index) 48 | { 49 | twin->readNextEntry(); 50 | } 51 | 52 | return std::unique_ptr(twin); 53 | } 54 | 55 | AbstractFileSystem * SshFileIterator::fs() const 56 | { 57 | return static_cast(m_fs.get()); 58 | } 59 | 60 | bool SshFileIterator::valid() const 61 | { 62 | return (m_dir != nullptr && !m_filename.empty()); 63 | } 64 | 65 | std::string SshFileIterator::path() const 66 | { 67 | return m_path; 68 | } 69 | 70 | int SshFileIterator::index() const 71 | { 72 | return m_index; 73 | } 74 | 75 | std::string SshFileIterator::name() const 76 | { 77 | return m_filename; 78 | } 79 | 80 | void SshFileIterator::next() 81 | { 82 | readNextEntry(); 83 | } 84 | 85 | void SshFileIterator::readNextEntry() 86 | { 87 | // Check directory handle 88 | if (!m_dir) return; 89 | 90 | // Read next entry 91 | char name[512]; 92 | char longName[512]; 93 | 94 | int size = libssh2_sftp_readdir_ex(m_dir, name, sizeof(name), longName, sizeof(longName), &m_attrs); 95 | m_index++; 96 | 97 | if (size <= 0) 98 | { 99 | m_filename = ""; 100 | return; 101 | } 102 | 103 | // Omit '.' and '..' 104 | m_filename = name; 105 | while (m_filename == ".." || m_filename == ".") 106 | { 107 | size = libssh2_sftp_readdir_ex(m_dir, name, sizeof(name), longName, sizeof(longName), &m_attrs); 108 | 109 | if (size <= 0) 110 | { 111 | m_filename = ""; 112 | break; 113 | } 114 | 115 | m_filename = name; 116 | } 117 | } 118 | 119 | 120 | } // namespace cppfs 121 | -------------------------------------------------------------------------------- /source/cppfs/source/ssh/SshInputStreamBuffer.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | 14 | #ifdef max 15 | #undef max 16 | #endif 17 | 18 | 19 | namespace cppfs 20 | { 21 | 22 | 23 | SshInputStreamBuffer::SshInputStreamBuffer(std::shared_ptr fs, const std::string & path, std::ios_base::openmode, size_t bufferSize, size_t putbackSize) 24 | : m_fs(fs) 25 | , m_path(path) 26 | , m_file(nullptr) 27 | , m_putbackSize(std::max(putbackSize, (size_t)1)) 28 | , m_buffer(std::max(bufferSize, m_putbackSize) + m_putbackSize) 29 | { 30 | // Check handle 31 | if (!m_fs->m_session) return; 32 | 33 | // Initialize SFTP sub-protocol 34 | m_fs->initSftp(); 35 | 36 | // Check handle 37 | if (!m_fs->m_sftpSession) return; 38 | 39 | // Open file 40 | m_file = (void *)libssh2_sftp_open((LIBSSH2_SFTP *)m_fs->m_sftpSession, m_path.c_str(), LIBSSH2_FXF_READ, 0); 41 | 42 | if (m_file) 43 | { 44 | // Initialize read buffer 45 | char * end = &m_buffer.front() + m_buffer.size(); 46 | setg(end, end, end); 47 | } 48 | 49 | else 50 | { 51 | // Error, close file 52 | libssh2_sftp_close((LIBSSH2_SFTP_HANDLE *)m_file); 53 | } 54 | } 55 | 56 | SshInputStreamBuffer::~SshInputStreamBuffer() 57 | { 58 | if (m_file) 59 | { 60 | libssh2_sftp_close((LIBSSH2_SFTP_HANDLE *)m_file); 61 | } 62 | } 63 | 64 | std::streambuf::int_type SshInputStreamBuffer::underflow() 65 | { 66 | // Check file handle 67 | if (!m_file) 68 | { 69 | return traits_type::eof(); 70 | } 71 | 72 | // Check if the buffer is filled 73 | if (gptr() < egptr()) 74 | { 75 | // Return next byte from buffer 76 | return traits_type::to_int_type(*gptr()); 77 | } 78 | 79 | // Prepare buffer 80 | char * base = &m_buffer.front(); 81 | char * start = base; 82 | 83 | if (eback() == base) 84 | { 85 | std::memmove(base, egptr() - m_putbackSize, m_putbackSize); 86 | start += m_putbackSize; 87 | } 88 | 89 | // Refill buffer 90 | size_t size = m_buffer.size() - (start - base); 91 | ssize_t n = libssh2_sftp_read((LIBSSH2_SFTP_HANDLE *)m_file, start, size); 92 | 93 | // EOF 94 | if (n == 0) 95 | { 96 | return traits_type::eof(); 97 | } 98 | 99 | // Set buffer pointers 100 | setg(base, start, start + n); 101 | 102 | // Return next byte 103 | return traits_type::to_int_type(*gptr()); 104 | } 105 | 106 | SshInputStreamBuffer::pos_type SshInputStreamBuffer::seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which) 107 | { 108 | if (way == std::ios_base::beg) 109 | { 110 | return seekpos((pos_type)off, which); 111 | } 112 | 113 | else if (way == std::ios_base::end) 114 | { 115 | LIBSSH2_SFTP_ATTRIBUTES attrs; 116 | 117 | if (libssh2_sftp_fstat_ex((LIBSSH2_SFTP_HANDLE *)m_file, &attrs, 0) == 0) 118 | { 119 | pos_type pos = (pos_type)attrs.filesize + off; 120 | return seekpos(pos, which); 121 | } 122 | } 123 | 124 | else if (way == std::ios_base::cur) 125 | { 126 | pos_type pos = (pos_type)libssh2_sftp_tell64((LIBSSH2_SFTP_HANDLE *)m_file); 127 | pos += off - (egptr() - gptr()); 128 | 129 | return seekpos(pos, which); 130 | } 131 | 132 | return (pos_type)(off_type)(-1); 133 | } 134 | 135 | SshInputStreamBuffer::pos_type SshInputStreamBuffer::seekpos(pos_type pos, std::ios_base::openmode) 136 | { 137 | // Check file handle 138 | if (!m_file) 139 | { 140 | return (pos_type)(off_type)(-1); 141 | } 142 | 143 | // Set file position 144 | libssh2_sftp_seek64((LIBSSH2_SFTP_HANDLE *)m_file, (libssh2_uint64_t)pos); 145 | 146 | // Reset read buffer 147 | char * end = &m_buffer.front() + m_buffer.size(); 148 | setg(end, end, end); 149 | 150 | // Return new position 151 | return (pos_type)(off_type)(pos); 152 | } 153 | 154 | 155 | } // namespace cppfs 156 | -------------------------------------------------------------------------------- /source/cppfs/source/system.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | 7 | namespace 8 | { 9 | 10 | std::string obtainHomeDir() 11 | { 12 | #if defined(SYSTEM_WINDOWS) 13 | return std::string(getenv("HOMEPATH")); 14 | #else 15 | return std::string(getenv("HOME")); 16 | #endif 17 | } 18 | 19 | std::string obtainConfigDir() 20 | { 21 | #if defined(SYSTEM_WINDOWS) 22 | return std::string(getenv("APPDATA")) + "\\"; 23 | #elif defined(SYSTEM_DARWIN) 24 | return std::string(getenv("HOME")) + "/Library/Preferences/"; 25 | #else 26 | return std::string(getenv("HOME")) + "/.config/"; 27 | #endif 28 | } 29 | 30 | } // namespace 31 | 32 | 33 | namespace cppfs 34 | { 35 | 36 | 37 | namespace system 38 | { 39 | 40 | 41 | const std::string & homeDir() 42 | { 43 | static const std::string dir = obtainHomeDir(); 44 | 45 | return dir; 46 | } 47 | 48 | std::string configDir(const std::string & application) 49 | { 50 | static const std::string dir = obtainConfigDir(); 51 | 52 | return dir + application; 53 | } 54 | 55 | 56 | } // namespace system 57 | 58 | 59 | } // namespace cppfs 60 | -------------------------------------------------------------------------------- /source/cppfs/source/windows/LocalFileIterator.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | namespace cppfs 11 | { 12 | 13 | 14 | LocalFileIterator::LocalFileIterator(std::shared_ptr fs, const std::string & path) 15 | : m_fs(fs) 16 | , m_path(path) 17 | , m_index(-1) 18 | , m_findHandle(nullptr) 19 | , m_findData(nullptr) 20 | { 21 | // Create find data 22 | m_findData = static_cast(new WIN32_FIND_DATA); 23 | 24 | // Read first directory entry 25 | readNextEntry(); 26 | } 27 | 28 | LocalFileIterator::~LocalFileIterator() 29 | { 30 | // Close search 31 | if (m_findHandle) 32 | { 33 | FindClose(m_findHandle); 34 | } 35 | 36 | // Destroy find data 37 | delete static_cast(m_findData); 38 | } 39 | 40 | std::unique_ptr LocalFileIterator::clone() const 41 | { 42 | auto * twin = new LocalFileIterator(m_fs, m_path); 43 | 44 | while (twin->m_index < m_index) 45 | { 46 | twin->readNextEntry(); 47 | } 48 | 49 | return std::unique_ptr(twin); 50 | } 51 | 52 | AbstractFileSystem * LocalFileIterator::fs() const 53 | { 54 | return static_cast(m_fs.get()); 55 | } 56 | 57 | bool LocalFileIterator::valid() const 58 | { 59 | return (m_findHandle != nullptr); 60 | } 61 | 62 | std::string LocalFileIterator::path() const 63 | { 64 | return m_path; 65 | } 66 | 67 | int LocalFileIterator::index() const 68 | { 69 | return m_index; 70 | } 71 | 72 | std::string LocalFileIterator::name() const 73 | { 74 | // Check directory and entry handle 75 | if (!m_findHandle) 76 | { 77 | return ""; 78 | } 79 | 80 | // Return filename of current item 81 | return std::string(static_cast(m_findData)->cFileName); 82 | } 83 | 84 | void LocalFileIterator::next() 85 | { 86 | readNextEntry(); 87 | } 88 | 89 | void LocalFileIterator::readNextEntry() 90 | { 91 | std::string filename; 92 | 93 | do 94 | { 95 | // Check find handle 96 | if (!m_findHandle) 97 | { 98 | // Open directory 99 | std::string query = FilePath(m_path).fullPath() + "/*"; 100 | m_findHandle = FindFirstFileA(query.c_str(), static_cast(m_findData)); 101 | 102 | // Abort if directory could not be opened 103 | if (m_findHandle == INVALID_HANDLE_VALUE) 104 | { 105 | m_findHandle = nullptr; 106 | return; 107 | } 108 | } 109 | 110 | else { 111 | // Read next entry 112 | if (!FindNextFile(m_findHandle, static_cast(m_findData))) 113 | { 114 | // No more files, close 115 | FindClose(m_findHandle); 116 | m_findHandle = nullptr; 117 | return; 118 | } 119 | } 120 | 121 | // Advance index 122 | m_index++; 123 | 124 | // Get filename 125 | filename = std::string(static_cast(m_findData)->cFileName); 126 | } while (filename == ".." || filename == "."); 127 | } 128 | 129 | 130 | } // namespace cppfs 131 | -------------------------------------------------------------------------------- /source/cppfs/source/windows/LocalFileSystem.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | namespace cppfs 10 | { 11 | 12 | 13 | LocalFileSystem::LocalFileSystem() 14 | { 15 | } 16 | 17 | LocalFileSystem::~LocalFileSystem() 18 | { 19 | } 20 | 21 | FileHandle LocalFileSystem::open(const std::string & path) 22 | { 23 | return open(std::string(path)); 24 | } 25 | 26 | FileHandle LocalFileSystem::open(std::string && path) 27 | { 28 | return FileHandle( 29 | std::unique_ptr( 30 | new LocalFileHandle(shared_from_this(), path) 31 | ) 32 | ); 33 | } 34 | 35 | std::unique_ptr LocalFileSystem::createFileWatcher(FileWatcher & fileWatcher) 36 | { 37 | return std::unique_ptr( 38 | new LocalFileWatcher(&fileWatcher, shared_from_this()) 39 | ); 40 | } 41 | 42 | 43 | } // namespace cppfs 44 | -------------------------------------------------------------------------------- /source/examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # Check if examples are enabled 3 | if(NOT OPTION_BUILD_EXAMPLES) 4 | return() 5 | endif() 6 | 7 | # Example applications 8 | add_subdirectory(cppfs-ls) 9 | add_subdirectory(cppfs-cat) 10 | add_subdirectory(cppfs-cp) 11 | add_subdirectory(cppfs-ln) 12 | add_subdirectory(cppfs-tree) 13 | add_subdirectory(cppfs-sync) 14 | add_subdirectory(cppfs-watch) 15 | -------------------------------------------------------------------------------- /source/examples/cppfs-cat/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # External dependencies 4 | # 5 | 6 | find_package(cppassist REQUIRED) 7 | 8 | 9 | # 10 | # Executable name and options 11 | # 12 | 13 | # Target name 14 | set(target cppfs-cat) 15 | 16 | # Exit here if required dependencies are not met 17 | message(STATUS "Example ${target}") 18 | 19 | 20 | # 21 | # Sources 22 | # 23 | 24 | set(sources 25 | main.cpp 26 | ) 27 | 28 | 29 | # 30 | # Create executable 31 | # 32 | 33 | # Build executable 34 | add_executable(${target} 35 | ${sources} 36 | ) 37 | 38 | # Create namespaced alias 39 | add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) 40 | 41 | 42 | # 43 | # Project options 44 | # 45 | 46 | set_target_properties(${target} 47 | PROPERTIES 48 | ${DEFAULT_PROJECT_OPTIONS} 49 | FOLDER "${IDE_FOLDER}" 50 | ) 51 | 52 | 53 | # 54 | # Include directories 55 | # 56 | 57 | target_include_directories(${target} 58 | PRIVATE 59 | ${DEFAULT_INCLUDE_DIRECTORIES} 60 | ${PROJECT_BINARY_DIR}/source/include 61 | ) 62 | 63 | 64 | # 65 | # Libraries 66 | # 67 | 68 | target_link_libraries(${target} 69 | PRIVATE 70 | ${DEFAULT_LIBRARIES} 71 | cppassist::cppassist 72 | ${META_PROJECT_NAME}::cppfs 73 | ) 74 | 75 | 76 | # 77 | # Compile definitions 78 | # 79 | 80 | target_compile_definitions(${target} 81 | PRIVATE 82 | ${DEFAULT_COMPILE_DEFINITIONS} 83 | ) 84 | 85 | 86 | # 87 | # Compile options 88 | # 89 | 90 | target_compile_options(${target} 91 | PRIVATE 92 | ${DEFAULT_COMPILE_OPTIONS} 93 | ) 94 | 95 | 96 | # 97 | # Linker options 98 | # 99 | 100 | target_link_libraries(${target} 101 | PRIVATE 102 | ${DEFAULT_LINKER_OPTIONS} 103 | ) 104 | 105 | 106 | # 107 | # Target Health 108 | # 109 | 110 | perform_health_checks( 111 | ${target} 112 | ${sources} 113 | ) 114 | 115 | 116 | # 117 | # Deployment 118 | # 119 | 120 | # Executable 121 | install(TARGETS ${target} 122 | RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT examples 123 | BUNDLE DESTINATION ${INSTALL_BIN} COMPONENT examples 124 | ) 125 | -------------------------------------------------------------------------------- /source/examples/cppfs-cat/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | using namespace cppassist; 18 | using namespace cppfs; 19 | 20 | 21 | int main(int argc, char * argv[]) 22 | { 23 | // Declare program 24 | CommandLineProgram program( 25 | "cppfs-cat", 26 | "cppfs-cat " CPPFS_VERSION, 27 | "Print file to console." 28 | ); 29 | 30 | CommandLineAction action("cat", "Print file to console"); 31 | program.add(&action); 32 | 33 | CommandLineSwitch swHelp("--help", "-h", "Print help text", CommandLineSwitch::Optional); 34 | action.add(&swHelp); 35 | 36 | CommandLineOption opConfig("--config", "-c", "file", "Load configuration from file", CommandLineOption::Optional); 37 | action.add(&opConfig); 38 | 39 | CommandLineSwitch swBase64("--base64", "", "Encode file in base64", CommandLineSwitch::Optional); 40 | action.add(&swBase64); 41 | 42 | CommandLineParameter paramPath("path", CommandLineParameter::NonOptional); 43 | action.add(¶mPath); 44 | 45 | // Parse command line 46 | program.parse(argc, argv); 47 | if (program.hasErrors() || swHelp.activated()) 48 | { 49 | // Print help and exit 50 | program.print(program.help()); 51 | return 0; 52 | } 53 | 54 | // Get login credentials 55 | LoginCredentials login; 56 | 57 | std::string configFile = opConfig.value(); 58 | if (!configFile.empty()) 59 | { 60 | login.load(configFile); 61 | } 62 | 63 | // Get path 64 | std::string path = paramPath.value(); 65 | 66 | // Open file 67 | FileHandle file = fs::open(path, &login); 68 | if (file.isFile()) 69 | { 70 | // Output file content 71 | std::string content = swBase64.activated() ? file.base64() : file.readFile(); 72 | std::cout << content << std::endl; 73 | 74 | // Done 75 | return 0; 76 | } 77 | 78 | // Error 79 | std::cout << "'" << path << "' is not a valid file." << std::endl; 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /source/examples/cppfs-cp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # External dependencies 4 | # 5 | 6 | find_package(cppassist REQUIRED) 7 | 8 | 9 | # 10 | # Executable name and options 11 | # 12 | 13 | # Target name 14 | set(target cppfs-cp) 15 | 16 | # Exit here if required dependencies are not met 17 | message(STATUS "Example ${target}") 18 | 19 | 20 | # 21 | # Sources 22 | # 23 | 24 | set(sources 25 | main.cpp 26 | ) 27 | 28 | 29 | # 30 | # Create executable 31 | # 32 | 33 | # Build executable 34 | add_executable(${target} 35 | ${sources} 36 | ) 37 | 38 | # Create namespaced alias 39 | add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) 40 | 41 | 42 | # 43 | # Project options 44 | # 45 | 46 | set_target_properties(${target} 47 | PROPERTIES 48 | ${DEFAULT_PROJECT_OPTIONS} 49 | FOLDER "${IDE_FOLDER}" 50 | ) 51 | 52 | 53 | # 54 | # Include directories 55 | # 56 | 57 | target_include_directories(${target} 58 | PRIVATE 59 | ${DEFAULT_INCLUDE_DIRECTORIES} 60 | ${PROJECT_BINARY_DIR}/source/include 61 | ) 62 | 63 | 64 | # 65 | # Libraries 66 | # 67 | 68 | target_link_libraries(${target} 69 | PRIVATE 70 | ${DEFAULT_LIBRARIES} 71 | cppassist::cppassist 72 | ${META_PROJECT_NAME}::cppfs 73 | ) 74 | 75 | 76 | # 77 | # Compile definitions 78 | # 79 | 80 | target_compile_definitions(${target} 81 | PRIVATE 82 | ${DEFAULT_COMPILE_DEFINITIONS} 83 | ) 84 | 85 | 86 | # 87 | # Compile options 88 | # 89 | 90 | target_compile_options(${target} 91 | PRIVATE 92 | ${DEFAULT_COMPILE_OPTIONS} 93 | ) 94 | 95 | 96 | # 97 | # Linker options 98 | # 99 | 100 | target_link_libraries(${target} 101 | PRIVATE 102 | ${DEFAULT_LINKER_OPTIONS} 103 | ) 104 | 105 | 106 | # 107 | # Target Health 108 | # 109 | 110 | perform_health_checks( 111 | ${target} 112 | ${sources} 113 | ) 114 | 115 | 116 | # 117 | # Deployment 118 | # 119 | 120 | # Executable 121 | install(TARGETS ${target} 122 | RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT examples 123 | BUNDLE DESTINATION ${INSTALL_BIN} COMPONENT examples 124 | ) 125 | -------------------------------------------------------------------------------- /source/examples/cppfs-cp/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | using namespace cppassist; 17 | using namespace cppfs; 18 | 19 | 20 | int main(int argc, char * argv[]) 21 | { 22 | // Declare program 23 | CommandLineProgram program( 24 | "cppfs-cp", 25 | "cppfs-cp " CPPFS_VERSION, 26 | "Copy file." 27 | ); 28 | 29 | CommandLineAction action("cp", "Copy file"); 30 | program.add(&action); 31 | 32 | CommandLineSwitch swHelp("--help", "-h", "Print help text", CommandLineSwitch::Optional); 33 | action.add(&swHelp); 34 | 35 | CommandLineOption opConfig("--config", "-c", "file", "Load configuration from file", CommandLineOption::Optional); 36 | action.add(&opConfig); 37 | 38 | CommandLineParameter paramSrc("src", CommandLineParameter::NonOptional); 39 | action.add(¶mSrc); 40 | 41 | CommandLineParameter paramDst("dst", CommandLineParameter::NonOptional); 42 | action.add(¶mDst); 43 | 44 | // Parse command line 45 | program.parse(argc, argv); 46 | if (program.hasErrors() || swHelp.activated()) 47 | { 48 | // Print help and exit 49 | program.print(program.help()); 50 | return 0; 51 | } 52 | 53 | // Get login credentials 54 | LoginCredentials login; 55 | 56 | std::string configFile = opConfig.value(); 57 | if (!configFile.empty()) 58 | { 59 | login.load(configFile); 60 | } 61 | 62 | // Get source and destination path 63 | std::string src = paramSrc.value(); 64 | std::string dst = paramDst.value(); 65 | 66 | // Open file handles 67 | FileHandle srcFile = fs::open(src, &login); 68 | FileHandle dstFile = fs::open(dst, &login); 69 | 70 | if (srcFile.isFile()) 71 | { 72 | // Copy file 73 | srcFile.copy(dstFile); 74 | 75 | // Done 76 | return 0; 77 | } 78 | 79 | else 80 | { 81 | // Error 82 | std::cout << "'" << src << "' is not a valid file." << std::endl; 83 | } 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /source/examples/cppfs-ln/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # External dependencies 4 | # 5 | 6 | find_package(cppassist REQUIRED) 7 | 8 | 9 | # 10 | # Executable name and options 11 | # 12 | 13 | # Target name 14 | set(target cppfs-ln) 15 | 16 | # Exit here if required dependencies are not met 17 | message(STATUS "Example ${target}") 18 | 19 | 20 | # 21 | # Sources 22 | # 23 | 24 | set(sources 25 | main.cpp 26 | ) 27 | 28 | 29 | # 30 | # Create executable 31 | # 32 | 33 | # Build executable 34 | add_executable(${target} 35 | ${sources} 36 | ) 37 | 38 | # Create namespaced alias 39 | add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) 40 | 41 | 42 | # 43 | # Project options 44 | # 45 | 46 | set_target_properties(${target} 47 | PROPERTIES 48 | ${DEFAULT_PROJECT_OPTIONS} 49 | FOLDER "${IDE_FOLDER}" 50 | ) 51 | 52 | 53 | # 54 | # Include directories 55 | # 56 | 57 | target_include_directories(${target} 58 | PRIVATE 59 | ${DEFAULT_INCLUDE_DIRECTORIES} 60 | ${PROJECT_BINARY_DIR}/source/include 61 | ) 62 | 63 | 64 | # 65 | # Libraries 66 | # 67 | 68 | target_link_libraries(${target} 69 | PRIVATE 70 | ${DEFAULT_LIBRARIES} 71 | cppassist::cppassist 72 | ${META_PROJECT_NAME}::cppfs 73 | ) 74 | 75 | 76 | # 77 | # Compile definitions 78 | # 79 | 80 | target_compile_definitions(${target} 81 | PRIVATE 82 | ${DEFAULT_COMPILE_DEFINITIONS} 83 | ) 84 | 85 | 86 | # 87 | # Compile options 88 | # 89 | 90 | target_compile_options(${target} 91 | PRIVATE 92 | ${DEFAULT_COMPILE_OPTIONS} 93 | ) 94 | 95 | 96 | # 97 | # Linker options 98 | # 99 | 100 | target_link_libraries(${target} 101 | PRIVATE 102 | ${DEFAULT_LINKER_OPTIONS} 103 | ) 104 | 105 | 106 | # 107 | # Target Health 108 | # 109 | 110 | perform_health_checks( 111 | ${target} 112 | ${sources} 113 | ) 114 | 115 | 116 | # 117 | # Deployment 118 | # 119 | 120 | # Executable 121 | install(TARGETS ${target} 122 | RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT examples 123 | BUNDLE DESTINATION ${INSTALL_BIN} COMPONENT examples 124 | ) 125 | -------------------------------------------------------------------------------- /source/examples/cppfs-ln/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | using namespace cppassist; 17 | using namespace cppfs; 18 | 19 | 20 | int main(int argc, char * argv[]) 21 | { 22 | // Declare program 23 | CommandLineProgram program( 24 | "cppfs-ln", 25 | "cppfs-ln " CPPFS_VERSION, 26 | "Create link." 27 | ); 28 | 29 | CommandLineAction action("ln", "Create link"); 30 | program.add(&action); 31 | 32 | CommandLineSwitch swHelp("--help", "-h", "Print help text", CommandLineSwitch::Optional); 33 | action.add(&swHelp); 34 | 35 | CommandLineOption opConfig("--config", "-c", "file", "Load configuration from file", CommandLineOption::Optional); 36 | action.add(&opConfig); 37 | 38 | CommandLineSwitch swSymbolic("--symbolic", "-s", "Create symbolic link", CommandLineSwitch::Optional); 39 | action.add(&swSymbolic); 40 | 41 | CommandLineParameter paramSrc("src", CommandLineParameter::NonOptional); 42 | action.add(¶mSrc); 43 | 44 | CommandLineParameter paramDst("dst", CommandLineParameter::NonOptional); 45 | action.add(¶mDst); 46 | 47 | // Parse command line 48 | program.parse(argc, argv); 49 | if (program.hasErrors() || swHelp.activated()) 50 | { 51 | // Print help and exit 52 | program.print(program.help()); 53 | return 0; 54 | } 55 | 56 | // Get login credentials 57 | LoginCredentials login; 58 | 59 | std::string configFile = opConfig.value(); 60 | if (!configFile.empty()) 61 | { 62 | login.load(configFile); 63 | } 64 | 65 | // Get source and destination path 66 | std::string src = paramSrc.value(); 67 | std::string dst = paramDst.value(); 68 | 69 | // Open file handles 70 | FileHandle srcFile = fs::open(src, &login); 71 | FileHandle dstFile = fs::open(dst, &login); 72 | 73 | if (srcFile.isFile()) 74 | { 75 | // Create link 76 | if (swSymbolic.activated()) srcFile.createSymbolicLink(dstFile); 77 | else srcFile.createLink(dstFile); 78 | 79 | // Done 80 | return 0; 81 | } 82 | 83 | else 84 | { 85 | // Error 86 | std::cout << "'" << src << "' is not a valid file." << std::endl; 87 | } 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /source/examples/cppfs-ls/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # External dependencies 4 | # 5 | 6 | find_package(cppassist REQUIRED) 7 | 8 | 9 | # 10 | # Executable name and options 11 | # 12 | 13 | # Target name 14 | set(target cppfs-ls) 15 | 16 | # Exit here if required dependencies are not met 17 | message(STATUS "Example ${target}") 18 | 19 | 20 | # 21 | # Sources 22 | # 23 | 24 | set(sources 25 | main.cpp 26 | ) 27 | 28 | 29 | # 30 | # Create executable 31 | # 32 | 33 | # Build executable 34 | add_executable(${target} 35 | ${sources} 36 | ) 37 | 38 | # Create namespaced alias 39 | add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) 40 | 41 | 42 | # 43 | # Project options 44 | # 45 | 46 | set_target_properties(${target} 47 | PROPERTIES 48 | ${DEFAULT_PROJECT_OPTIONS} 49 | FOLDER "${IDE_FOLDER}" 50 | ) 51 | 52 | 53 | # 54 | # Include directories 55 | # 56 | 57 | target_include_directories(${target} 58 | PRIVATE 59 | ${DEFAULT_INCLUDE_DIRECTORIES} 60 | ${PROJECT_BINARY_DIR}/source/include 61 | ) 62 | 63 | 64 | # 65 | # Libraries 66 | # 67 | 68 | target_link_libraries(${target} 69 | PRIVATE 70 | ${DEFAULT_LIBRARIES} 71 | cppassist::cppassist 72 | ${META_PROJECT_NAME}::cppfs 73 | ) 74 | 75 | 76 | # 77 | # Compile definitions 78 | # 79 | 80 | target_compile_definitions(${target} 81 | PRIVATE 82 | ${DEFAULT_COMPILE_DEFINITIONS} 83 | ) 84 | 85 | 86 | # 87 | # Compile options 88 | # 89 | 90 | target_compile_options(${target} 91 | PRIVATE 92 | ${DEFAULT_COMPILE_OPTIONS} 93 | ) 94 | 95 | 96 | # 97 | # Linker options 98 | # 99 | 100 | target_link_libraries(${target} 101 | PRIVATE 102 | ${DEFAULT_LINKER_OPTIONS} 103 | ) 104 | 105 | 106 | # 107 | # Target Health 108 | # 109 | 110 | perform_health_checks( 111 | ${target} 112 | ${sources} 113 | ) 114 | 115 | 116 | # 117 | # Deployment 118 | # 119 | 120 | # Executable 121 | install(TARGETS ${target} 122 | RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT examples 123 | BUNDLE DESTINATION ${INSTALL_BIN} COMPONENT examples 124 | ) 125 | -------------------------------------------------------------------------------- /source/examples/cppfs-ls/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | using namespace cppassist; 18 | using namespace cppfs; 19 | 20 | 21 | int main(int argc, char * argv[]) 22 | { 23 | // Declare program 24 | CommandLineProgram program( 25 | "cppfs-ls", 26 | "cppfs-ls " CPPFS_VERSION, 27 | "List all files in a directory." 28 | ); 29 | 30 | CommandLineAction action("list", "List files in directory"); 31 | program.add(&action); 32 | 33 | CommandLineSwitch swHelp("--help", "-h", "Print help text", CommandLineSwitch::Optional); 34 | action.add(&swHelp); 35 | 36 | CommandLineOption opConfig("--config", "-c", "file", "Load configuration from file", CommandLineOption::Optional); 37 | action.add(&opConfig); 38 | 39 | CommandLineParameter paramPath("path", CommandLineParameter::Optional); 40 | action.add(¶mPath); 41 | 42 | // Parse command line 43 | program.parse(argc, argv); 44 | if (program.hasErrors() || swHelp.activated()) 45 | { 46 | // Print help and exit 47 | program.print(program.help()); 48 | return 0; 49 | } 50 | 51 | // Get login credentials 52 | LoginCredentials login; 53 | 54 | std::string configFile = opConfig.value(); 55 | if (!configFile.empty()) 56 | { 57 | login.load(configFile); 58 | } 59 | 60 | // Get path 61 | std::string path = paramPath.value(); 62 | if (path.empty()) path = "."; 63 | 64 | // Open directory 65 | FileHandle dir = fs::open(path, &login); 66 | if (dir.isDirectory()) 67 | { 68 | // List files 69 | for (auto it = dir.begin(); it != dir.end(); ++it) 70 | { 71 | std::cout << "- " << *it; 72 | 73 | FileHandle f = dir.open(*it); 74 | if (f.isDirectory()) { 75 | std::cout << " (DIR)"; 76 | } else if (f.isSymbolicLink()) { 77 | std::cout << " (LNK)"; 78 | } 79 | 80 | std::cout << std::endl; 81 | } 82 | } 83 | else 84 | { 85 | std::cout << "'" << path << "' is not a valid directory." << std::endl; 86 | } 87 | 88 | // Done 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /source/examples/cppfs-sync/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # External dependencies 4 | # 5 | 6 | find_package(cppassist REQUIRED) 7 | 8 | 9 | # 10 | # Executable name and options 11 | # 12 | 13 | # Target name 14 | set(target cppfs-sync) 15 | 16 | # Exit here if required dependencies are not met 17 | message(STATUS "Example ${target}") 18 | 19 | 20 | # 21 | # Sources 22 | # 23 | 24 | set(sources 25 | main.cpp 26 | ) 27 | 28 | 29 | # 30 | # Create executable 31 | # 32 | 33 | # Build executable 34 | add_executable(${target} 35 | ${sources} 36 | ) 37 | 38 | # Create namespaced alias 39 | add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) 40 | 41 | 42 | # 43 | # Project options 44 | # 45 | 46 | set_target_properties(${target} 47 | PROPERTIES 48 | ${DEFAULT_PROJECT_OPTIONS} 49 | FOLDER "${IDE_FOLDER}" 50 | ) 51 | 52 | 53 | # 54 | # Include directories 55 | # 56 | 57 | target_include_directories(${target} 58 | PRIVATE 59 | ${DEFAULT_INCLUDE_DIRECTORIES} 60 | ${PROJECT_BINARY_DIR}/source/include 61 | ) 62 | 63 | 64 | # 65 | # Libraries 66 | # 67 | 68 | target_link_libraries(${target} 69 | PRIVATE 70 | ${DEFAULT_LIBRARIES} 71 | cppassist::cppassist 72 | ${META_PROJECT_NAME}::cppfs 73 | ) 74 | 75 | 76 | # 77 | # Compile definitions 78 | # 79 | 80 | target_compile_definitions(${target} 81 | PRIVATE 82 | ${DEFAULT_COMPILE_DEFINITIONS} 83 | ) 84 | 85 | 86 | # 87 | # Compile options 88 | # 89 | 90 | target_compile_options(${target} 91 | PRIVATE 92 | ${DEFAULT_COMPILE_OPTIONS} 93 | ) 94 | 95 | 96 | # 97 | # Linker options 98 | # 99 | 100 | target_link_libraries(${target} 101 | PRIVATE 102 | ${DEFAULT_LINKER_OPTIONS} 103 | ) 104 | 105 | 106 | # 107 | # Target Health 108 | # 109 | 110 | perform_health_checks( 111 | ${target} 112 | ${sources} 113 | ) 114 | 115 | 116 | # 117 | # Deployment 118 | # 119 | 120 | # Executable 121 | install(TARGETS ${target} 122 | RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT examples 123 | BUNDLE DESTINATION ${INSTALL_BIN} COMPONENT examples 124 | ) 125 | -------------------------------------------------------------------------------- /source/examples/cppfs-sync/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | using namespace cppassist; 19 | using namespace cppfs; 20 | 21 | 22 | int main(int argc, char * argv[]) 23 | { 24 | // Declare program 25 | CommandLineProgram program( 26 | "cppfs-sync", 27 | "cppfs-sync " CPPFS_VERSION, 28 | "Sync directories." 29 | ); 30 | 31 | CommandLineAction action("sync", "Sync directories"); 32 | program.add(&action); 33 | 34 | CommandLineSwitch swHelp("--help", "-h", "Print help text", CommandLineSwitch::Optional); 35 | action.add(&swHelp); 36 | 37 | CommandLineOption opConfig("--config", "-c", "file", "Load configuration from file", CommandLineOption::Optional); 38 | action.add(&opConfig); 39 | 40 | CommandLineParameter paramSrc("src", CommandLineParameter::NonOptional); 41 | action.add(¶mSrc); 42 | 43 | CommandLineParameter paramDst("dst", CommandLineParameter::NonOptional); 44 | action.add(¶mDst); 45 | 46 | // Parse command line 47 | program.parse(argc, argv); 48 | if (program.hasErrors() || swHelp.activated()) 49 | { 50 | // Print help and exit 51 | program.print(program.help()); 52 | return 0; 53 | } 54 | 55 | // Get login credentials 56 | LoginCredentials login; 57 | 58 | std::string configFile = opConfig.value(); 59 | if (!configFile.empty()) 60 | { 61 | login.load(configFile); 62 | } 63 | 64 | // Get source and destination path 65 | std::string src = paramSrc.value(); 66 | std::string dst = paramDst.value(); 67 | 68 | // Open directory handles 69 | FileHandle srcDir = fs::open(src, &login); 70 | FileHandle dstDir = fs::open(dst, &login); 71 | 72 | // Open source directory 73 | if (!srcDir.isDirectory()) 74 | { 75 | // Error 76 | std::cout << "Could not open source directory '" << src << "'." << std::endl; 77 | return 1; 78 | } 79 | 80 | // Open destination directory 81 | if (!dstDir.isDirectory()) 82 | { 83 | // Create destination directory 84 | dstDir.createDirectory(); 85 | 86 | // Check directory again 87 | if (!dstDir.isDirectory()) 88 | { 89 | // Error 90 | std::cout << "Could not open output directory '" << dst << "'." << std::endl; 91 | return 1; 92 | } 93 | } 94 | 95 | // Get both directory trees 96 | auto srcTree = srcDir.readTree(); 97 | auto dstTree = dstDir.readTree(); 98 | 99 | // Compute differences 100 | auto diff = dstTree->createDiff(*srcTree.get()); 101 | 102 | // Apply changes to destination 103 | for (Change change : diff->changes()) 104 | { 105 | if (change.operation() == Change::CopyFile) { 106 | FileHandle src = srcDir.open(change.path()); 107 | FileHandle dst = dstDir.open(change.path()); 108 | src.copy(dst); 109 | } 110 | 111 | if (change.operation() == Change::CopyDir) { 112 | FileHandle src = srcDir.open(change.path()); 113 | FileHandle dst = dstDir.open(change.path()); 114 | src.copyDirectoryRec(dst); 115 | } 116 | 117 | if (change.operation() == Change::RemoveFile) { 118 | FileHandle dst = dstDir.open(change.path()); 119 | dst.remove(); 120 | } 121 | 122 | if (change.operation() == Change::RemoveDir) { 123 | FileHandle dst = dstDir.open(change.path()); 124 | dst.removeDirectoryRec(); 125 | } 126 | } 127 | 128 | // Done 129 | return 0; 130 | } 131 | -------------------------------------------------------------------------------- /source/examples/cppfs-tree/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # External dependencies 4 | # 5 | 6 | find_package(cppassist REQUIRED) 7 | 8 | 9 | # 10 | # Executable name and options 11 | # 12 | 13 | # Target name 14 | set(target cppfs-tree) 15 | 16 | # Exit here if required dependencies are not met 17 | message(STATUS "Example ${target}") 18 | 19 | 20 | # 21 | # Sources 22 | # 23 | 24 | set(sources 25 | main.cpp 26 | ) 27 | 28 | 29 | # 30 | # Create executable 31 | # 32 | 33 | # Build executable 34 | add_executable(${target} 35 | ${sources} 36 | ) 37 | 38 | # Create namespaced alias 39 | add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) 40 | 41 | 42 | # 43 | # Project options 44 | # 45 | 46 | set_target_properties(${target} 47 | PROPERTIES 48 | ${DEFAULT_PROJECT_OPTIONS} 49 | FOLDER "${IDE_FOLDER}" 50 | ) 51 | 52 | 53 | # 54 | # Include directories 55 | # 56 | 57 | target_include_directories(${target} 58 | PRIVATE 59 | ${DEFAULT_INCLUDE_DIRECTORIES} 60 | ${PROJECT_BINARY_DIR}/source/include 61 | ) 62 | 63 | 64 | # 65 | # Libraries 66 | # 67 | 68 | target_link_libraries(${target} 69 | PRIVATE 70 | ${DEFAULT_LIBRARIES} 71 | cppassist::cppassist 72 | ${META_PROJECT_NAME}::cppfs 73 | ) 74 | 75 | 76 | # 77 | # Compile definitions 78 | # 79 | 80 | target_compile_definitions(${target} 81 | PRIVATE 82 | ${DEFAULT_COMPILE_DEFINITIONS} 83 | ) 84 | 85 | 86 | # 87 | # Compile options 88 | # 89 | 90 | target_compile_options(${target} 91 | PRIVATE 92 | ${DEFAULT_COMPILE_OPTIONS} 93 | ) 94 | 95 | 96 | # 97 | # Linker options 98 | # 99 | 100 | target_link_libraries(${target} 101 | PRIVATE 102 | ${DEFAULT_LINKER_OPTIONS} 103 | ) 104 | 105 | 106 | # 107 | # Target Health 108 | # 109 | 110 | perform_health_checks( 111 | ${target} 112 | ${sources} 113 | ) 114 | 115 | 116 | # 117 | # Deployment 118 | # 119 | 120 | # Executable 121 | install(TARGETS ${target} 122 | RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT examples 123 | BUNDLE DESTINATION ${INSTALL_BIN} COMPONENT examples 124 | ) 125 | -------------------------------------------------------------------------------- /source/examples/cppfs-tree/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | using namespace cppassist; 18 | using namespace cppfs; 19 | 20 | 21 | int main(int argc, char * argv[]) 22 | { 23 | // Declare program 24 | CommandLineProgram program( 25 | "cppfs-tree", 26 | "cppfs-tree " CPPFS_VERSION, 27 | "Print directory tree." 28 | ); 29 | 30 | CommandLineAction action("tree", "Print directory tree"); 31 | program.add(&action); 32 | 33 | CommandLineSwitch swHelp("--help", "-h", "Print help text", CommandLineSwitch::Optional); 34 | action.add(&swHelp); 35 | 36 | CommandLineOption opConfig("--config", "-c", "file", "Load configuration from file", CommandLineOption::Optional); 37 | action.add(&opConfig); 38 | 39 | CommandLineParameter paramPath("path", CommandLineParameter::Optional); 40 | action.add(¶mPath); 41 | 42 | // Parse command line 43 | program.parse(argc, argv); 44 | if (program.hasErrors() || swHelp.activated()) 45 | { 46 | // Print help and exit 47 | program.print(program.help()); 48 | return 0; 49 | } 50 | 51 | // Get login credentials 52 | LoginCredentials login; 53 | 54 | std::string configFile = opConfig.value(); 55 | if (!configFile.empty()) 56 | { 57 | login.load(configFile); 58 | } 59 | 60 | // Get path 61 | std::string path = paramPath.value(); 62 | if (path.empty()) path = "."; 63 | 64 | // Open directory 65 | FileHandle dir = fs::open(path, &login); 66 | if (!dir.isDirectory()) 67 | { 68 | // Error 69 | std::cout << "Could not open directory '" << path << "'." << std::endl; 70 | return 1; 71 | } 72 | 73 | // Get directory tree 74 | auto tree = dir.readTree(); 75 | 76 | // Print tree 77 | tree->print(); 78 | std::cout << std::endl; 79 | 80 | // Done 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /source/examples/cppfs-watch/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # External dependencies 4 | # 5 | 6 | find_package(cppassist REQUIRED) 7 | 8 | 9 | # 10 | # Executable name and options 11 | # 12 | 13 | # Target name 14 | set(target cppfs-watch) 15 | 16 | # Exit here if required dependencies are not met 17 | message(STATUS "Example ${target}") 18 | 19 | 20 | # 21 | # Sources 22 | # 23 | 24 | set(sources 25 | main.cpp 26 | ) 27 | 28 | 29 | # 30 | # Create executable 31 | # 32 | 33 | # Build executable 34 | add_executable(${target} 35 | ${sources} 36 | ) 37 | 38 | # Create namespaced alias 39 | add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) 40 | 41 | 42 | # 43 | # Project options 44 | # 45 | 46 | set_target_properties(${target} 47 | PROPERTIES 48 | ${DEFAULT_PROJECT_OPTIONS} 49 | FOLDER "${IDE_FOLDER}" 50 | ) 51 | 52 | 53 | # 54 | # Include directories 55 | # 56 | 57 | target_include_directories(${target} 58 | PRIVATE 59 | ${DEFAULT_INCLUDE_DIRECTORIES} 60 | ${PROJECT_BINARY_DIR}/source/include 61 | ) 62 | 63 | 64 | # 65 | # Libraries 66 | # 67 | 68 | target_link_libraries(${target} 69 | PRIVATE 70 | ${DEFAULT_LIBRARIES} 71 | cppassist::cppassist 72 | ${META_PROJECT_NAME}::cppfs 73 | ) 74 | 75 | 76 | # 77 | # Compile definitions 78 | # 79 | 80 | target_compile_definitions(${target} 81 | PRIVATE 82 | ${DEFAULT_COMPILE_DEFINITIONS} 83 | ) 84 | 85 | 86 | # 87 | # Compile options 88 | # 89 | 90 | target_compile_options(${target} 91 | PRIVATE 92 | ${DEFAULT_COMPILE_OPTIONS} 93 | ) 94 | 95 | 96 | # 97 | # Linker options 98 | # 99 | 100 | target_link_libraries(${target} 101 | PRIVATE 102 | ${DEFAULT_LINKER_OPTIONS} 103 | ) 104 | 105 | 106 | # 107 | # Target Health 108 | # 109 | 110 | perform_health_checks( 111 | ${target} 112 | ${sources} 113 | ) 114 | 115 | 116 | # 117 | # Deployment 118 | # 119 | 120 | # Executable 121 | install(TARGETS ${target} 122 | RUNTIME DESTINATION ${INSTALL_BIN} COMPONENT examples 123 | BUNDLE DESTINATION ${INSTALL_BIN} COMPONENT examples 124 | ) 125 | -------------------------------------------------------------------------------- /source/examples/cppfs-watch/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | using namespace cppassist; 20 | using namespace cppfs; 21 | 22 | 23 | int main(int argc, char * argv[]) 24 | { 25 | // Declare program 26 | CommandLineProgram program( 27 | "cppfs-watch", 28 | "cppfs-watch " CPPFS_VERSION, 29 | "Listen to events in the file system and print them to the console." 30 | ); 31 | 32 | CommandLineAction action("watch", "Watch files in directory"); 33 | program.add(&action); 34 | 35 | CommandLineSwitch swHelp("--help", "-h", "Print help text", CommandLineSwitch::Optional); 36 | action.add(&swHelp); 37 | 38 | CommandLineSwitch swRecursive("--recursive", "-r", "Watcher directories recursively", CommandLineSwitch::Optional); 39 | action.add(&swRecursive); 40 | 41 | CommandLineOption opTime("--timeout", "-t", "seconds", "Timeout after which to stop (in seconds)", CommandLineOption::Optional); 42 | action.add(&opTime); 43 | 44 | action.setOptionalParametersAllowed(true); 45 | action.setOptionalParameterName("path"); 46 | 47 | // Parse command line 48 | program.parse(argc, argv); 49 | if (program.hasErrors() || swHelp.activated()) 50 | { 51 | // Print help and exit 52 | program.print(program.help()); 53 | return 0; 54 | } 55 | 56 | // Execute file watching 57 | try { 58 | // Create file watcher 59 | FileWatcher watcher; 60 | 61 | // Get recursive mode 62 | RecursiveMode recursive = swRecursive.activated() ? Recursive : NonRecursive; 63 | 64 | // Get paths to watch 65 | auto paths = action.optionalParameters(); 66 | if (paths.size() < 1) { 67 | paths.push_back("."); 68 | } 69 | 70 | // Add directories to watcher 71 | for (auto path : paths) 72 | { 73 | // Open directory 74 | FileHandle dir = fs::open(path); 75 | if (dir.isDirectory()) 76 | { 77 | std::cout << "Watching '" << path << "'" << std::endl; 78 | 79 | // Watch directory 80 | watcher.add(dir, FileCreated | FileRemoved | FileModified | FileAttrChanged, recursive); 81 | } 82 | else 83 | { 84 | // Invalid directory 85 | std::cout << "'" << path << "' is not a valid directory." << std::endl; 86 | } 87 | } 88 | 89 | // Create file event handler 90 | watcher.addHandler([] (FileHandle & fh, FileEvent event) { 91 | // Get file type 92 | std::string type = (fh.isDirectory() ? "directory" : "file"); 93 | 94 | // Get operation 95 | std::string operation = ( (event & FileCreated) ? "created" : 96 | ( (event & FileRemoved) ? "removed" : 97 | ( (event & FileAttrChanged) ? "attributes changed" : 98 | "modified" ) ) ); 99 | 100 | // Log event 101 | std::cout << "The " << type << " '" << fh.path() << "' was " << operation << "." << std::endl; 102 | }); 103 | 104 | // Begin watching and printing events 105 | std::string t = opTime.value(); 106 | if (t.empty()) { 107 | // No timeout given 108 | while (true) { 109 | watcher.watch(); 110 | } 111 | } 112 | else { 113 | // Get timeout 114 | auto timeout = std::stoi(t); 115 | std::cout << "Will stop watching after " << timeout << " seconds..." << std::endl; 116 | 117 | // Get current time 118 | auto start = std::chrono::system_clock::now(); 119 | auto now = std::chrono::system_clock::now(); 120 | 121 | // Execute watch loop 122 | while (std::chrono::duration_cast(std::chrono::system_clock::now() - start).count() < timeout) 123 | { 124 | // Timeout 500ms to revive the main loop 125 | watcher.watch(500); 126 | 127 | // Check elapsed time 128 | now = std::chrono::system_clock::now(); 129 | } 130 | } 131 | } catch (std::exception& e) { 132 | // Error during execution 133 | std::cerr << "Exception: " << e.what() << std::endl; 134 | return -1; 135 | } 136 | 137 | // Done 138 | return 0; 139 | } 140 | -------------------------------------------------------------------------------- /source/scripts/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Add project health scripts as cmake targets 4 | # 5 | 6 | add_custom_target( 7 | check-template 8 | COMMAND ${CMAKE_COMMAND} 9 | -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} 10 | -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} 11 | -DAPPLIED_CMAKE_INIT_SHA=${META_CMAKE_INIT_SHA} 12 | -P ${PROJECT_SOURCE_DIR}/cmake/CheckTemplate.cmake 13 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 14 | ) 15 | -------------------------------------------------------------------------------- /source/scripts/check_template.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | WORKING_DIRECTORY=`pwd` 4 | 5 | if [ $# -lt 2 ]; then 6 | echo "$0 has to be called using two parameters" 7 | exit 1 8 | fi 9 | 10 | TEMPLATE_PATH="$1" 11 | PROJECT_PATH="$2" 12 | 13 | cd $WORKING_DIRECTORY 14 | cd $TEMPLATE_PATH 15 | 16 | CMAKE_INIT_SHA1_HASH=`git log -n 1 --pretty="%H"` 17 | 18 | cd $WORKING_DIRECTORY 19 | cd $PROJECT_PATH 20 | 21 | PROJECT_SHA1_HASH=`git log --oneline | grep -i "cmake-init" | grep -o -E "[0-9a-f]{40}" | head -n 1` 22 | 23 | if [ "$CMAKE_INIT_SHA1_HASH" == "$PROJECT_SHA1_HASH" ]; then 24 | echo "cmake-init template is up-to-date ($CMAKE_INIT_SHA1_HASH)" 25 | else 26 | echo "cmake-init template needs an update: https://github.com/cginternals/cmake-init/compare/$PROJECT_SHA1_HASH...master" 27 | fi 28 | -------------------------------------------------------------------------------- /source/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # Configure test project and environment 4 | # 5 | 6 | # CMake version 7 | cmake_minimum_required(VERSION 3.0 FATAL_ERROR) 8 | 9 | # Meta information about the project 10 | set(META_PROJECT_NAME "cppfs") 11 | 12 | # Declare project 13 | project("${META_PROJECT_NAME}-tests" C CXX) 14 | 15 | # Set policies 16 | set_policy(CMP0028 NEW) # ENABLE CMP0028: Double colon in target name means ALIAS or IMPORTED target. 17 | set_policy(CMP0054 NEW) # ENABLE CMP0054: Only interpret if() arguments as variables or keywords when unquoted. 18 | set_policy(CMP0042 NEW) # ENABLE CMP0042: MACOSX_RPATH is enabled by default. 19 | set_policy(CMP0063 NEW) # ENABLE CMP0063: Honor visibility properties for all target types. 20 | 21 | # Compiler settings and options 22 | 23 | if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake") 24 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/CompileOptions.cmake) 25 | include(${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/Custom.cmake) 26 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake") 27 | else() 28 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/CompileOptions.cmake) 29 | include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Custom.cmake) 30 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 31 | endif() 32 | 33 | # Function: Build test and add command to execute it via target 'test' 34 | function(add_test_without_ctest target) 35 | add_subdirectory(${target}) 36 | 37 | if(NOT TARGET ${target}) 38 | return() 39 | endif() 40 | 41 | add_dependencies(test ${target}) 42 | add_custom_command(TARGET test POST_BUILD 43 | COMMAND $ --gtest_output=xml:gtests-${target}.xml 44 | ) 45 | endfunction() 46 | 47 | find_package(googletest QUIET) 48 | 49 | if (NOT TARGET googletest::googletest) 50 | message(STATUS "Tests skipped: googletest not found") 51 | return() 52 | endif () 53 | 54 | 55 | # 56 | # Target 'test' 57 | # 58 | 59 | if (${CMAKE_VERSION} VERSION_LESS "3.11") 60 | set_policy(CMP0037 OLD) # DISABLE CMP0037: Target names should be reserved and should match a validity pattern. 61 | add_custom_target(test) 62 | set_target_properties(test PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1) 63 | else () 64 | if (NOT TARGET test) 65 | add_custom_target(test) 66 | set_target_properties(test PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1) 67 | endif() 68 | endif () 69 | 70 | 71 | # 72 | # Tests 73 | # 74 | 75 | add_test_without_ctest(cppfs-test) 76 | -------------------------------------------------------------------------------- /source/tests/cppfs-test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # External dependencies 4 | # 5 | 6 | find_package(${META_PROJECT_NAME} REQUIRED HINTS "${CMAKE_CURRENT_SOURCE_DIR}/../../../") 7 | 8 | 9 | # 10 | # Executable name and options 11 | # 12 | 13 | # Target name 14 | set(target cppfs-test) 15 | message(STATUS "Test ${target}") 16 | 17 | 18 | # 19 | # Sources 20 | # 21 | 22 | set(sources 23 | main.cpp 24 | FilePath_test.cpp 25 | ) 26 | 27 | 28 | # 29 | # Create executable 30 | # 31 | 32 | # Build executable 33 | add_executable(${target} 34 | ${sources} 35 | ) 36 | 37 | # Create namespaced alias 38 | add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) 39 | 40 | 41 | # 42 | # Project options 43 | # 44 | 45 | set_target_properties(${target} 46 | PROPERTIES 47 | ${DEFAULT_PROJECT_OPTIONS} 48 | FOLDER "${IDE_FOLDER}" 49 | ) 50 | 51 | 52 | # 53 | # Include directories 54 | # 55 | 56 | target_include_directories(${target} 57 | PRIVATE 58 | ${DEFAULT_INCLUDE_DIRECTORIES} 59 | ${PROJECT_BINARY_DIR}/source/include 60 | ) 61 | 62 | 63 | # 64 | # Libraries 65 | # 66 | 67 | target_link_libraries(${target} 68 | PRIVATE 69 | ${DEFAULT_LIBRARIES} 70 | ${META_PROJECT_NAME}::cppfs 71 | googletest::googletest 72 | ) 73 | 74 | 75 | # 76 | # Compile definitions 77 | # 78 | 79 | target_compile_definitions(${target} 80 | PRIVATE 81 | ${DEFAULT_COMPILE_DEFINITIONS} 82 | ) 83 | 84 | 85 | # 86 | # Compile options 87 | # 88 | 89 | target_compile_options(${target} 90 | PRIVATE 91 | ${DEFAULT_COMPILE_OPTIONS} 92 | ) 93 | 94 | 95 | # 96 | # Linker options 97 | # 98 | 99 | target_link_libraries(${target} 100 | PRIVATE 101 | ${DEFAULT_LINKER_OPTIONS} 102 | ) 103 | -------------------------------------------------------------------------------- /source/tests/cppfs-test/FilePath_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | 7 | class FilePath_test: public testing::Test 8 | { 9 | public: 10 | }; 11 | 12 | 13 | TEST_F(FilePath_test, testResolved) 14 | { 15 | // Taken from documentation of FilePath::resolved 16 | const auto f1 = cppfs::FilePath("a/b/../c"); // -> "a/c" 17 | const auto f2 = cppfs::FilePath("../../a"); // -> "../../a" 18 | const auto f3 = cppfs::FilePath("a/../../b"); // -> "../b" 19 | const auto f4 = cppfs::FilePath("/a/../b/"); // -> "/b" 20 | 21 | // Taken from https://github.com/cginternals/cppfs/issues/38 22 | const auto f5 = cppfs::FilePath("/usr/bin/bash"); // "/usr/bin/bash" 23 | const auto f6 = cppfs::FilePath("/usr/bin/../bin/bash"); // "/usr/bin/bash" 24 | const auto f7 = cppfs::FilePath("/usr/bin//../bin/bash"); // -> "/usr/bin/bash" 25 | 26 | EXPECT_EQ("a/c", f1.resolved()); 27 | EXPECT_EQ("../../a", f2.resolved()); 28 | EXPECT_EQ("../b", f3.resolved()); 29 | EXPECT_EQ("/b", f4.resolved()); 30 | EXPECT_EQ("/usr/bin/bash", f5.resolved()); 31 | EXPECT_EQ("/usr/bin/bash", f6.resolved()); 32 | EXPECT_EQ("/usr/bin/bash", f7.resolved()); 33 | } 34 | -------------------------------------------------------------------------------- /source/tests/cppfs-test/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | 5 | int main(int argc, char* argv[]) 6 | { 7 | ::testing::InitGoogleMock(&argc, argv); 8 | return RUN_ALL_TESTS(); 9 | } 10 | -------------------------------------------------------------------------------- /source/version.h.in: -------------------------------------------------------------------------------- 1 | 2 | #define ${META_PROJECT_ID}_PROJECT_NAME "@META_PROJECT_NAME@" 3 | #define ${META_PROJECT_ID}_PROJECT_DESCRIPTION "@META_PROJECT_DESCRIPTION@" 4 | 5 | #define ${META_PROJECT_ID}_AUTHOR_ORGANIZATION "@META_AUTHOR_ORGANIZATION@" 6 | #define ${META_PROJECT_ID}_AUTHOR_DOMAIN "@META_AUTHOR_DOMAIN@" 7 | #define ${META_PROJECT_ID}_AUTHOR_MAINTAINER "@META_AUTHOR_MAINTAINER@" 8 | 9 | #define ${META_PROJECT_ID}_VERSION_MAJOR "@META_VERSION_MAJOR@" 10 | #define ${META_PROJECT_ID}_VERSION_MINOR "@META_VERSION_MINOR@" 11 | #define ${META_PROJECT_ID}_VERSION_PATCH "@META_VERSION_PATCH@" 12 | #define ${META_PROJECT_ID}_VERSION_REVISION "@META_VERSION_REVISION@" 13 | 14 | #define ${META_PROJECT_ID}_VERSION "@META_VERSION@" 15 | #define ${META_PROJECT_ID}_NAME_VERSION "@META_NAME_VERSION@" 16 | --------------------------------------------------------------------------------