From b1235638fb2e1cf7bd9e22a9c2bc43f876540153 Mon Sep 17 00:00:00 2001 From: Jim Borden Date: Tue, 12 Mar 2019 11:03:04 +0900 Subject: [PATCH] Refactor CMake and add missing API --- .gitignore | 1 + CMakeLists.txt | 230 ++++++++--------------------- cmake/platform_android.cmake | 18 +++ cmake/platform_apple.cmake | 31 ++++ cmake/platform_linux.cmake | 6 + cmake/platform_linux_desktop.cmake | 17 +++ cmake/platform_win.cmake | 56 +++++++ include/cbl/CBLBase.h | 6 + include/cbl/CBLBlob.h | 1 + include/cbl/CBLLog.h | 66 +++++++++ include/cbl/CBLReplicator.h | 14 ++ include/cbl/CBL_Compat.h | 8 +- include/cbl/cbl_config.h.in | 20 +++ src/CBLDatabase.cc | 18 ++- src/CBLLog.cc | 50 +++++++ src/CBLQuery.cc | 2 +- 16 files changed, 363 insertions(+), 181 deletions(-) create mode 100644 cmake/platform_android.cmake create mode 100644 cmake/platform_apple.cmake create mode 100644 cmake/platform_linux.cmake create mode 100644 cmake/platform_linux_desktop.cmake create mode 100644 cmake/platform_win.cmake create mode 100644 include/cbl/CBLLog.h create mode 100644 include/cbl/cbl_config.h.in create mode 100644 src/CBLLog.cc diff --git a/.gitignore b/.gitignore index c7b7081e..21051b92 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ build_cmake python/CouchbaseLite/libcouchbase_lite.dylib python/CouchbaseLite/PyCBL.c .vscode +empty.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 95224f6d..33eac429 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,189 +16,102 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_STANDARD 11) -option(CODE_COVERAGE_ENABLED "Set whether or not code coverage information should be generated" OFF) option(BUILD_ENTERPRISE "Set whether or not to build enterprise edition" OFF) -add_definitions(-DCMAKE # Let the source know this is a CMAKE build - -D__STDC_LIMIT_MACROS # Ensure the presence of UINT64_MAX, etc - -DNOMINMAX # Get rid of pesky Windows macros for min and max - -DHAVE_LOCALTIME_R - -DHAVE_USLEEP - -DHAVE_UTIME) - if(BUILD_ENTERPRISE) add_definitions(-DCOUCHBASE_ENTERPRISE) # Tells CBL it's an EE build endif() +add_definitions("-DCMAKE") +include(CheckIncludeFile) +include (CheckFunctionExists) +check_include_file(unistd.h CBL_HAVE_UNISTD_H) +check_include_file(direct.h CBL_HAVE_DIRECT_H) +check_function_exists(vasprintf, CBL_HAVE_VASPRINTF) + +configure_file( + "${PROJECT_SOURCE_DIR}/include/cbl/cbl_config.h.in" + "${PROJECT_BINARY_DIR}/include/cbl/cbl_config.h" +) if(MSVC) - if(WINDOWS_STORE) - add_definitions(-D_WIN32_WINNT=0x0602) # Support back to Windows 8 for Windows Store - else() - add_definitions(-D_WIN32_WINNT=0x0601 # Support back to Windows 7 for Windows desktop - -DINCL_EXTRA_HTON_FUNCTIONS)# Make sure htonll is defined for WebSocketProtocol.hh - endif() + include("cmake/platform_win.cmake") elseif(ANDROID) - # See: https://github.com/android-ndk/ndk/issues/477 - # The issue is also applicable for other areas like fseeko - add_definitions(-D_FILE_OFFSET_BITS=32) + include("cmake/platform_android.cmake") +elseif(APPLE) + include("cmake/platform_apple.cmake") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + include("cmake/platform_linux.cmake") +else() + message(FATAL_ERROR "Unknown platform") endif() +init_vars() +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CBL_C_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CBL_CXX_FLAGS}") set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$:DEBUG> ) -if(CODE_COVERAGE_ENABLED) - if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug" AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -O0") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -O0") - elseif(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - message(WARN " Code coverage not supported for non-debug builds") - else() - message(WARN " Code coverage only supported on Clang") - endif() -endif() - - -if(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8 /EHsc /wd4068 /wd4244 /wd4018 /wd4819 /wd4800 -D_CRT_SECURE_NO_WARNINGS=1") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8 -D_CRT_SECURE_NO_WARNINGS=1") -endif() - -if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") - add_definitions(-DLITECORE_USES_ICU=1) - - # Enable relative RPATHs for installed bits - set (CMAKE_INSTALL_RPATH "\$ORIGIN") - - if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - message(FATAL_ERROR "${CMAKE_CXX_COMPILER_ID} is not supported for building!") - endif() - find_library(LIBCXX_LIB c++) - if (NOT LIBCXX_LIB) - message(FATAL_ERROR "libc++ not found") - endif() - message("Found libc++ at ${LIBCXX_LIB}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - - find_library(LIBCXXABI_LIB c++abi) - if (NOT LIBCXXABI_LIB) - message(FATAL_ERROR "libc++abi not found") - endif() - message("Found libc++abi at ${LIBCXXABI_LIB}") - find_path(LIBCXX_INCLUDE c++/v1/string - HINTS "${CMAKE_BINARY_DIR}/tlm/deps/libcxx.exploded" - PATH_SUFFIXES include) - if (NOT LIBCXX_INCLUDE) - message(FATAL_ERROR "libc++ header files not found") - endif() - message("Using libc++ header files in ${LIBCXX_INCLUDE}") - include_directories("${LIBCXX_INCLUDE}/c++/v1") - if(NOT EXISTS "/usr/include/xlocale.h") - include_directories("${LIBCXX_INCLUDE}/c++/v1/support/xlocale") # this fixed path is here to avoid compilation on Ubuntu 17.10 where xlocale.h is searched by some header(s) in libc++ as but not found from search path without this modification. However, only do it if the original xlocale.h does not exist since this will get searched before /usr/include and override a valid file with an empty one. - endif() - include_directories("/usr/include/libcxxabi") # this fixed path is here to avoid Clang issue noted at http://lists.alioth.debian.org/pipermail/pkg-llvm-team/2015-September/005208.html - endif() - find_library(ICU4C_COMMON icuuc) - if (NOT ICU4C_COMMON) - message(FATAL_ERROR "libicuuc not found") - endif() - message("Found libicuuc at ${ICU4C_COMMON}") - find_library(ICU4C_I18N icui18n) - if (NOT ICU4C_I18N) - message(FATAL_ERROR "libicui18n not found") - endif() - message("Found libicui18n at ${ICU4C_I18N}") - find_path(LIBICU_INCLUDE unicode/ucol.h - HINTS "${CMAKE_BINARY_DIR}/tlm/deps/icu4c.exploded" - PATH_SUFFIXES include) - if (NOT LIBICU_INCLUDE) - message(FATAL_ERROR "libicu header files not found") - endif() - message("Using libicu header files in ${LIBICU_INCLUDE}") - include_directories("${LIBICU_INCLUDE}") -endif() - -if(WIN32 OR ANDROID) - if(ANDROID) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libgcc.a") - endif() -endif() - ### SUBMODULES: include_directories("vendor/couchbase-lite-core/C/include" "vendor/couchbase-lite-core/vendor/fleece/API" "vendor/couchbase-lite-core/vendor/fleece/Fleece/Support") -if(WIN32) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /ignore:4099 /ignore:4221") - set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") -endif() add_subdirectory(vendor/couchbase-lite-core EXCLUDE_FROM_ALL) -### MORE BUILD SETTINGS: - -# Generate file repo_version.h containing Git repo information, and add it to #include path: -set(GENERATED_HEADERS_DIR "${CMAKE_BINARY_DIR}/generated_headers") -file(MAKE_DIRECTORY "${GENERATED_HEADERS_DIR}") -if (UNIX) - execute_process(COMMAND /bin/bash "${PROJECT_SOURCE_DIR}/build_cmake/scripts/get_repo_version.sh" - "${GENERATED_HEADERS_DIR}/repo_version.h") -else() - execute_process(COMMAND powershell "${PROJECT_SOURCE_DIR}/build_cmake/scripts/get_repo_version.ps1" - "${GENERATED_HEADERS_DIR}/repo_version.h") -endif() -include_directories(${GENERATED_HEADERS_DIR}) - - ### SOURCE FILES: -include_directories(include/cbl src) - -# TODO: CMake docs say it's better to list the source files explicitly than use aux_source_directory -aux_source_directory(src SRC_FILES) - if(!MSVC) set_source_files_properties(${C_SRC} PROPERTIES COMPILE_FLAGS -Wno-return-type-c-linkage) endif() ### BUILDING THE LIBRARY: -set(ALL_SRC_FILES - ${SRC_FILES}) - -if(MSVC) - include_directories("vendor/fleece/MSVC") -endif() - -if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") - # libc++ is special - clang will introduce an implicit -lc++ when it is used. - # That means we need to tell the linker the path to the directory containing - # libc++.so rather than just linking the .so directly. This must be done - # *before* the target declaration as it affects all subsequent targets. - get_filename_component (LIBCXX_LIBDIR "${LIBCXX_LIB}" DIRECTORY) - link_directories (${LIBCXX_LIBDIR}) -endif() +set_platform_source_files(RESULT PLATFORM_SRC) +set( + ALL_SRC_FILES + src/CBLBase.cc + src/CBLBlob.cc + src/CBLDatabase.cc + src/CBLDocument.cc + src/CBLLog.cc + src/CBLQuery.cc + src/CBLReplicator.cc + src/Listener.cc + src/Util.cc + ${PLATFORM_SRC} +) add_library(CouchbaseLiteCStatic STATIC ${ALL_SRC_FILES}) +target_include_directories(CouchbaseLiteCStatic PUBLIC include/cbl) +set_platform_include_directories(RESULT PLATFORM_INCLUDE) +target_include_directories( + CouchbaseLiteCStatic + PRIVATE + src + vendor/couchbase-lite-core/C + ${PROJECT_BINARY_DIR}/include/cbl/ + ${PLATFORM_INCLUDE} +) -if(WIN32) - add_library(CouchbaseLiteC SHARED MSVC/SQLiteTempDirectory.cc) #No-op for non-UWP -else() - file(WRITE empty.cpp) - add_library(CouchbaseLiteC SHARED empty.cpp) -endif() +file(WRITE empty.cpp) +add_library(CouchbaseLiteC SHARED empty.cpp) +target_include_directories(CouchbaseLiteC PUBLIC include/cbl) +target_include_directories( + CouchbaseLiteC + PRIVATE + src + vendor/couchbase-lite-core/C + ${PROJECT_BINARY_DIR}/include/cbl/ + ${PLATFORM_INCLUDE} +) install (TARGETS CouchbaseLiteC RUNTIME DESTINATION bin - LIBRARY DESTINATION lib) - -if(UNIX AND NOT APPLE) - set(WHOLE_LIBRARY_FLAG "-Wl,--whole-archive") - set(NO_WHOLE_LIBRARY_FLAG "-Wl,--no-whole-archive") -endif() + LIBRARY DESTINATION lib + PUBLIC_HEADER DESTINATION include) set(CBL_LIBRARIES_PRIVATE ${WHOLE_LIBRARY_FLAG} CouchbaseLiteCStatic @@ -213,30 +126,7 @@ set(CBL_LIBRARIES_PRIVATE ${WHOLE_LIBRARY_FLAG} target_link_libraries(CouchbaseLiteC PRIVATE ${CBL_LIBRARIES_PRIVATE}) -# Mac/iOS stuff -if (APPLE) - set_target_properties(CouchbaseLiteC PROPERTIES LINK_FLAGS - "-exported_symbols_list ${PROJECT_SOURCE_DIR}/src/CBL.exp") - target_link_libraries(CouchbaseLiteC PUBLIC "-framework CoreFoundation" - "-framework Foundation" - "-framework CFNetwork" - "-framework Security" - z) -elseif(UNIX AND NOT ANDROID) - target_link_libraries(CouchbaseLiteC PUBLIC z ${ICU4C_COMMON} ${ICU4C_I18N}) -elseif(ANDROID) - target_compile_definitions(CouchbaseLiteCStatic PUBLIC -D_CRYPTO_MBEDTLS) - target_link_libraries(CouchbaseLiteC PRIVATE "atomic" "log" zlibstatic) -else() - if(WINDOWS_STORE) - target_compile_definitions(CouchbaseLiteCStatic PUBLIC -DMBEDTLS_NO_PLATFORM_ENTROPY) - set_target_properties(CouchbaseLiteC PROPERTIES COMPILE_FLAGS /ZW) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /nodefaultlib:kernel32.lib /nodefaultlib:ole32.lib") - endif() - set_target_properties(CouchbaseLiteC PROPERTIES LINK_FLAGS - "/def:${PROJECT_SOURCE_DIR}/C/c4.def") - target_link_libraries(CouchbaseLiteC PRIVATE zlibstatic Ws2_32) -endif() +set_dylib_properties() ### TESTS: diff --git a/cmake/platform_android.cmake b/cmake/platform_android.cmake new file mode 100644 index 00000000..b383ea77 --- /dev/null +++ b/cmake/platform_android.cmake @@ -0,0 +1,18 @@ +include("${CMAKE_CURRENT_LIST_DIR}/platform_linux.cmake") + +function(set_platform_source_files) + # No-op +endfunction() + +function(set_platform_include_directories) + # No-op +endfunction() + +function(init_vars) + init_vars_linux() +endfunction() + +function(set_dylib_properties) + target_compile_definitions(CouchbaseLiteCStatic PRIVATE -D_CRYPTO_MBEDTLS) + target_link_libraries(CouchbaseLiteC PRIVATE atomic log zlibstatic) +endfunction() \ No newline at end of file diff --git a/cmake/platform_apple.cmake b/cmake/platform_apple.cmake new file mode 100644 index 00000000..2c8f5ba9 --- /dev/null +++ b/cmake/platform_apple.cmake @@ -0,0 +1,31 @@ +function(set_platform_source_files) + set(oneValueArgs RESULT) + cmake_parse_arguments(PLATFORM "" ${oneValueArgs} "" ${ARGN}) + if(NOT DEFINED PLATFORM_RESULT) + message(FATAL_ERROR set_platform_include_directories needs to be called with RESULT) + endif() + + set( + ${PLATFORM_RESULT} + src/dylib_main.cc + PARENT_SCOPE + ) +endfunction() + +function(set_platform_include_directories) + # No-op +endfunction() + +function(init_vars) + # No-op +endfunction() + +function(set_dylib_properties) + set_target_properties(CouchbaseLiteC PROPERTIES LINK_FLAGS + "-exported_symbols_list ${PROJECT_SOURCE_DIR}/src/CBL.exp") + target_link_libraries(CouchbaseLiteC PUBLIC "-framework CoreFoundation" + "-framework Foundation" + "-framework CFNetwork" + "-framework Security" + z) +endfunction() \ No newline at end of file diff --git a/cmake/platform_linux.cmake b/cmake/platform_linux.cmake new file mode 100644 index 00000000..e14fcf24 --- /dev/null +++ b/cmake/platform_linux.cmake @@ -0,0 +1,6 @@ + + +function(init_vars_linux) + set(WHOLE_LIBRARY_FLAG "-Wl,--whole-archive" CACHE INTERNAL "") + set(NO_WHOLE_LIBRARY_FLAG "-Wl,--no-whole-archive" CACHE INTERNAL "") +endfunction() \ No newline at end of file diff --git a/cmake/platform_linux_desktop.cmake b/cmake/platform_linux_desktop.cmake new file mode 100644 index 00000000..c25e60bd --- /dev/null +++ b/cmake/platform_linux_desktop.cmake @@ -0,0 +1,17 @@ +include("${CMAKE_CURRENT_LIST_DIR}/platform_linux.cmake") + +function(set_platform_source_files) + # No-op +endfunction() + +function(set_platform_include_directories) + # No-op +endfunction() + +function(init_vars) + init_vars_linux() +endfunction() + +function(set_dylib_properties) + target_link_libraries(CouchbaseLiteC PUBLIC z ${ICU4C_COMMON} ${ICU4C_I18N}) +endfunction() \ No newline at end of file diff --git a/cmake/platform_win.cmake b/cmake/platform_win.cmake new file mode 100644 index 00000000..e135e750 --- /dev/null +++ b/cmake/platform_win.cmake @@ -0,0 +1,56 @@ +function(set_platform_source_files) + # No platform specific +endfunction() + +function(set_platform_include_directories) + set(oneValueArgs RESULT) + cmake_parse_arguments(PLATFORM "" ${oneValueArgs} "" ${ARGN}) + if(NOT DEFINED PLATFORM_RESULT) + message(FATAL_ERROR set_platform_include_directories needs to be called with RESULT) + endif() + + set( + ${PLATFORM_RESULT} + vendor/couchbase-lite-core/include/MSVC + vendor/couchbase-lite-core/vendor/fleece/MSVC + PARENT_SCOPE + ) +endfunction() + +function(init_vars) + # Compile string literals as UTF-8, + # Enable exception handling for C++ but disable for extern C + # Disable the following warnings: + # 4068 (unrecognized pragma) + # 4099 (type first seen as struct now seen as class) + # Disable warning about "insecure" C runtime functions (strcpy vs strcpy_s) + string( + CONCAT CBL_CXX_FLAGS + "/utf-8 " + "/EHsc " + "/wd4068 " + "/wd4099 " + "-D_CRT_SECURE_NO_WARNINGS=1" + ) + set(CBL_CXX_FLAGS ${CBL_CXX_FLAGS} CACHE INTERNAL "") + + string( + CONCAT CBL_C_FLAGS + "/utf-8 " + "/wd4068 " + "-D_CRT_SECURE_NO_WARNINGS=1" + ) + set(CBL_C_FLAGS ${CBL_C_FLAGS} CACHE INTERNAL "") +endfunction() + +function(set_dylib_properties) + if(WINDOWS_STORE) + target_compile_definitions(CouchbaseLiteCStatic PRIVATE -DMBEDTLS_NO_PLATFORM_ENTROPY) + set_target_properties(CouchbaseLiteC PROPERTIES COMPILE_FLAGS /ZW) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /nodefaultlib:kernel32.lib /nodefaultlib:ole32.lib") + endif() + set_target_properties(CouchbaseLiteC PROPERTIES LINK_FLAGS + "/def:${PROJECT_SOURCE_DIR}/src/CBL.def") + target_link_libraries(CouchbaseLiteC PRIVATE zlibstatic Ws2_32) + target_compile_definitions(CouchbaseLiteCStatic PRIVATE LITECORE_EXPORTS) +endfunction() \ No newline at end of file diff --git a/include/cbl/CBLBase.h b/include/cbl/CBLBase.h index 1c24f190..5abfb993 100644 --- a/include/cbl/CBLBase.h +++ b/include/cbl/CBLBase.h @@ -17,7 +17,13 @@ // #pragma once +#ifdef CMAKE +#include "cbl_config.h" +#endif + #include "CBL_Compat.h" +#include +#include #ifdef __cplusplus extern "C" { diff --git a/include/cbl/CBLBlob.h b/include/cbl/CBLBlob.h index b11f8e4f..bc1429d5 100644 --- a/include/cbl/CBLBlob.h +++ b/include/cbl/CBLBlob.h @@ -19,6 +19,7 @@ #pragma once #include "CBLBase.h" #include "fleece/Fleece.h" +#include "PlatformCompat.hh" #ifdef __cplusplus extern "C" { diff --git a/include/cbl/CBLLog.h b/include/cbl/CBLLog.h new file mode 100644 index 00000000..0c25b466 --- /dev/null +++ b/include/cbl/CBLLog.h @@ -0,0 +1,66 @@ +// +// CBLLog.h +// +// Copyright © 2019 Couchbase. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once +#include "CBLBase.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \name Public API + @{ */ + +/** An object containing properties for file logging configuration + @warn \ref usePlaintext is not recommended for production */ +typedef struct { + const char* directory; ///< The directory to write logs to (UTF-8 encoded) + const uint32_t maxRotateCount; ///< The maximum number of *rotated* logs to keep (i.e. the total number of logs will be one more) + const size_t maxSize; ///< The max size to write to a log file before rotating (best-effort) + const bool usePlaintext; ///< Whether or not to log in plaintext +} CBLLogFileConfiguration; + +/** A callback function for handling log messages + @param level The level of the message being received + @param domain The domain of the message being received + @param message The message being received (UTF-8 encoded) */ +typedef void(*CBLLogCallback)(CBLLogLevel level, CBLLogDomain domain, const char* message); + +/** Gets the current log level for debug console logging */ +CBLLogLevel cbl_log_consoleLevel(); + +/** Sets the debug console log level */ +void cbl_log_setConsoleLevel(CBLLogLevel); + +/** Gets the current file logging config */ +const CBLLogFileConfiguration* cbl_log_fileConfig(); + +/** Sets the file logging configuration */ +void cbl_log_setFileConfig(CBLLogFileConfiguration); + +/** Gets the current log callback */ +CBLLogCallback cbl_log_callback(); + +/** Sets the callback for receiving log messages */ +void cbl_log_setCallback(CBLLogCallback); + +/** @} */ + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/cbl/CBLReplicator.h b/include/cbl/CBLReplicator.h index 66bb8ee5..98408927 100644 --- a/include/cbl/CBLReplicator.h +++ b/include/cbl/CBLReplicator.h @@ -24,6 +24,7 @@ extern "C" { #endif +CBL_CORE_API extern const char* kCBLAuthDefaultCookieName; /** \defgroup replication Replication A replicator is a background task that synchronizes changes between a local database and @@ -195,6 +196,19 @@ typedef void (*CBLReplicatedDocumentListener)(void *context, unsigned numDocuments, const CBLReplicatedDocument* documents); +/** A callback that notifies you when events occurred on a replicator. There are + multiple events per callback, each represented by a \ref CBLReplicatedDocument entry. + @param context The value given when the listener was added. + @param replicator The replicator. + @param documents The events that occurred + @param documentCount The size of the \ref documents array + @param isPush Whether or not this replicator is a push replicator */ +typedef void (*CBLDocumentReplicationListener)(void *context, + CBLReplicator *replicator _cbl_nonnull, + CBLReplicatedDocument** documents _cbl_nonnull, + size_t documentCount, + bool isPush); + /** Adds a listener that will be called when the replicator's status changes. */ CBLListenerToken* cbl_repl_addDocumentListener(CBLReplicator* _cbl_nonnull, CBLReplicatedDocumentListener _cbl_nonnull, diff --git a/include/cbl/CBL_Compat.h b/include/cbl/CBL_Compat.h index 7a65a25e..254ce5d6 100644 --- a/include/cbl/CBL_Compat.h +++ b/include/cbl/CBL_Compat.h @@ -29,11 +29,13 @@ #define __has_extension(x) 0 #endif + #ifdef _MSC_VER +#include #define CBLINLINE __forceinline -#define _cbl_nonnull -#define _cbl_returns_nonnull -#define _cbl_warn_unused +#define _cbl_nonnull _In_ +#define _cbl_returns_nonnull _Ret_notnull_ +#define _cbl_warn_unused _Check_return_ #else #define CBLINLINE inline #define _cbl_nonnull __attribute((nonnull)) diff --git a/include/cbl/cbl_config.h.in b/include/cbl/cbl_config.h.in new file mode 100644 index 00000000..1095d887 --- /dev/null +++ b/include/cbl/cbl_config.h.in @@ -0,0 +1,20 @@ +//Includes +#cmakedefine CBL_HAVE_UNISTD_H +#cmakedefine CBL_HAVE_DIRECT_H + +// Functions +#cmakedefine CBL_HAVE_VASPRINTF + +// Includes +#ifdef CBL_HAVE_UNISTD_H +#include +#endif + +#ifdef CBL_HAVE_DIRECT_H +#include +#endif + +// Functions +#ifndef CBL_HAVE_VASPRINTF +#include "asprintf.h" +#endif \ No newline at end of file diff --git a/src/CBLDatabase.cc b/src/CBLDatabase.cc index c8ff5ef3..de84ecef 100644 --- a/src/CBLDatabase.cc +++ b/src/CBLDatabase.cc @@ -20,8 +20,12 @@ #include "CBLPrivate.h" #include "Internal.hh" #include "Util.hh" +#include "PlatformCompat.hh" #include + +#ifndef CMAKE #include +#endif using namespace std; using namespace fleece; @@ -30,7 +34,7 @@ using namespace cbl_internal; // Default location for databases: the current directory static const char* defaultDbDir() { - static const string kDir = getcwd(nullptr, 0); + static const string kDir = cbl_getcwd(nullptr, 0); return kDir.c_str(); } @@ -39,13 +43,13 @@ static slice effectiveDir(const char *inDirectory) { } static C4DatabaseConfig2 asC4Config(const CBLDatabaseConfiguration *config) { - C4DatabaseConfig2 c4config { effectiveDir(config->directory) }; + C4DatabaseConfig2 c4Config { effectiveDir(config->directory) }; #ifdef COUCHBASE_ENTERPRISE - c4Config->encryptionKey.algorithm = config->encryptionKey.algorithm; - static_assert(sizeof(CBLEncryptionKey::bytes) == sizeof(C4EncryptionKey::bytes)); - memcpy(c4Config->encryptionKey.bytes, config->encryptionKey.bytes, sizeof(CBLEncryptionKey::bytes)); + c4Config.encryptionKey.algorithm = static_cast(config->encryptionKey.algorithm); + static_assert(sizeof(CBLEncryptionKey::bytes) == sizeof(C4EncryptionKey::bytes), "C4EncryptionKey and CBLEncryptionKey size do not match"); + memcpy(c4Config.encryptionKey.bytes, config->encryptionKey.bytes, sizeof(CBLEncryptionKey::bytes)); #endif - return c4config; + return c4Config; } @@ -86,7 +90,7 @@ CBLDatabase* cbl_db_open(const char *name, C4Database *c4db = c4db_openNamed(slice(name), &c4config, internal(outError)); if (!c4db) return nullptr; - return retain(new CBLDatabase(c4db, name, (config->directory ?: ""))); + return retain(new CBLDatabase(c4db, name, (config->directory ? config->directory : ""))); } diff --git a/src/CBLLog.cc b/src/CBLLog.cc new file mode 100644 index 00000000..abf1bb47 --- /dev/null +++ b/src/CBLLog.cc @@ -0,0 +1,50 @@ +// +// CBLLog.cc +// +// Copyright © 2019 Couchbase. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "CBLLog.h" +#include + +CBLLogLevel cbl_log_consoleLevel() +{ + abort(); +} + +void cbl_log_setConsoleLevel(CBLLogLevel) +{ + abort(); +} + +const CBLLogFileConfiguration* cbl_log_fileConfig() +{ + abort(); +} + +void cbl_log_setFileConfig(CBLLogFileConfiguration) +{ + abort(); +} + +CBLLogCallback cbl_log_callback() +{ + abort(); +} + +void cbl_log_setCallback(CBLLogCallback) +{ + abort(); +} \ No newline at end of file diff --git a/src/CBLQuery.cc b/src/CBLQuery.cc index 06ca7f13..2887cf4c 100644 --- a/src/CBLQuery.cc +++ b/src/CBLQuery.cc @@ -92,7 +92,7 @@ class CBLResultSet : public CBLRefCounted { } Value column(unsigned col) { - if (col < 64 && (_enum->missingColumns & (1<missingColumns & (1ULL<columns, uint32_t(col)); }